我正在努力学习JS/ES,对类和对象有点困惑。
下面的两个代码片段完全相同,但最后一个代码片段显然使用了一个类。但是第一个用法是什么?我以为一个类在执行时变成了对象?
我本以为clock
是一个函数,但它显然可以用作对象。为什么?
为什么有人会想使用类的方式,当第一个输入更短时?
var clock = {
start() {
setInterval(() => console.log(Date()), 1000)
}
}
clock.start()
和
class Clock {
start() {
setInterval(() => console.log(Date()), 1000)
}
}
const c = new Clock
c.start()
类是对象的模板。它们描述了一堆物体的行为。在javascript中,new Clock()
是如何获得类Clock
的新对象的。
对象文字语法({foo: 'bar'}
(是创建通用对象的快捷方式。因此,以这种方式创建的对象的类是Object
。此外,以这种方式创建对象并不能使new
对象具有相同的行为(从某种意义上说,这意味着它们属于同一类(。
在C++和Java等一些语言中,类是该语言的基本构建块。但在javascript中,它只是一个概念,基本上意味着(非正式地(任何具有相同指定行为的对象。更正式地说,尽管它是一个在其原型链中具有类原型的对象。什么是原型和原型链?好吧,每个*对象(即使是那些使用对象字面语法创建的对象(都有一个原型作为隐藏的**属性。在对象中查找属性时,如果在对象本身中找不到该属性,则会在原型中查找该属性。如果原型对象没有这个属性,它会"向上"检查原型的原型是否有这个属性,并尽可能地继续这样做。
当您使用class
语法时,您正在为类创建的每个对象在原型上设置属性。因此,在您的示例中,将函数start
分配给每个Clock
对象的原型。但是如果你把它分配给对象本身,那么它就不会使用原型。
有趣的是,类也是对象(它们可以有属性和方法(。
有关官方文件,请参阅此处:
- https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS
- https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes
*:您可以使用Object.create(null)
制作一个没有原型的对象,但这种情况很少见。这样做的好处是,您不会意外地访问原型的属性,因为根本没有。
**:您有时可以使用不推荐使用的__poto__
属性来访问原型。首选的新方法是Object.getPrototypeOf(object)
以下是一些您可以探索的示例:
const clockByLiteral = { start(){/* do something */} }
function startClock () { /* do something */}
class Clock {
start() { /* do something */}
}
const clock1 = new Clock()
const clock2 = new Clock()
function getClassName(object){
return object.constructor.name
}
console.log('"class" of clockByLiteral:', getClassName(clockByLiteral))
console.log('"class" of clockByLiteral.start:', getClassName(clockByLiteral.start))
console.log('"class" of startClock:', getClassName(startClock))
console.log('"class" of Clock class:', getClassName(Clock))
console.log('"class" of clock1:', getClassName(clock1))
console.log('"class" of clock2:', getClassName(clock2))
console.log('is the constructor of clock1 Clock?:', clock1.constructor === Clock, "(meaning that classes and constructors are the same objects, and are functions also")
console.log('is the prototype of clock1 Clock.prototype?:', Object.getPrototypeOf(clock1) === Clock.prototype)
console.log('is clock1 the same object as clock2?:', clock1 === clock2)
console.log('is clock1.start the same as clock2.start?:', clock1.start === clock2.start)
console.log('is clock1.start the same as Clock.prototype.start?:', clock1.start === Clock.prototype.start)
console.log('is clock1 an "instance" of Clock?:', clock1 instanceof Clock)
console.log('is clock1 an "instance" of Object?:', clock1 instanceof Object)
console.log('is clock1 an "instance" of Function?:', clock1 instanceof Function)
console.log('is Clock an "instance" of Function?:', Clock instanceof Function)
console.log('is startClock an "instance" of Function?:', Clock instanceof Function)
console.log('is startClock an "instance" of Object?:', Clock instanceof Object)