看这个 javascript 代码,function Foo(){}. 书上说这个是一个 constructor. 你可以这样来构造一个对象:var foo1 = new Foo();

但你真正理解了它的含义嘛?

作为一个 c++ 程序员,你会不会很自然的把 Foo 看作一个类? 错! 这里的 Foo,正如书上说的,是一个构造函数!既然它是构造函数,那么它对应的类是神马? 其实就是 Foo.prototype

如何从这个类得到它的构造函数? 很简单,就是 Foo.prototype.constructor. 上面代码创建的 foo1 对象,其实就是 Foo.prototype 的一个实例,在 javascript 中,类/实例的关系是如何确立的呢? 其实每一个对象里都有一个隐含的 .proto 指针(v8引擎中为 .__proto__) , 这个 .proto 指针就指向了 Foo.prototype. 而 .proto 指针就是在 new Foo() 时被初始化为 Foo().prototype 的.

j1.png

其实,Object, Array 等都是构造函数,他们对应的类则是 Object.prototype, Array.prototype. Foo.prototype 类完整的继承关系是 (省略了 constructor 指针):

j2.png

有几个值得注意的地方:

  • 只有 constructor 才有 .prototype 属性, 类和实例都没有
  • 只有实例(比如 foo1)和类(比如Foo().prototype)才有 .proto 指针
  • 因为你可以调用 Foo(); 这并不意味着类型 Foo().prototype 是一个 functor 类. 所以这样的代码有运行时错误: foo1();