新实例的默认原型是什么?

时间:2013-07-24 18:34:08

标签: javascript

我不明白以下行为:

var Foo = function () {};
var Bar = function () {};
Foo.prototype = Bar;
var foo = new Foo();
console.log(foo.prototype === Bar.prototype); // true, but why?

我在the spec中找不到关于使用构造函数创建的对象上prototype属性的默认值的任何内容。 (我确实发现this part of the spec提到,对于函数,prototype属性默认为new Object(),但没有提及使用构造函数创建的对象。)

所以,我的问题实际上是双重的:

使用构造函数创建的对象上prototype属性的默认值是多少? (看起来它是构造函数的prototype属性的prototype属性;例如Foo.prototype.prototype

它在哪里解释了规范中的这种行为?

2 个答案:

答案 0 :(得分:2)

构造对象的原型是构造函数的.prototype属性引用的对象。

因为foo.__proto__ === Bar,显然是foo.__proto__.prototype = Bar.prototype

foo对象没有.prototype属性,它在foo.__proto__中查找并找到,因为对象的原型是一个具有原型属性的函数对象,这就是你错过的

答案 1 :(得分:2)

  

使用构造函数创建的对象上的prototype属性的默认值是什么?

undefined,除非你正在构建的是一个函数。 prototype属性属于函数。如果实例对象的prortype链中没有函数对象(即instanceObj instanceof Functionfalse),则该实例通常不具有prototype属性。

函数具有prototype属性的原因是因为任何函数有一天可能会被用作构造函数。构造函数的prototype属性确定其构造实例的[[Prototype]]内部属性。

  

(看起来它是构造函数的prototype属性的prototype属性;例如Foo.prototype.prototype

您只能看到行为,因为您已将Foo.prototype 分配给函数Bar 。因此,当您尝试获取foo.prototype时,解释程序会查找foo的原型链,并在函数prototype上找到Bar属性。

特别是foo.prototype === Bar.prototype是正确的,因为:

  1. 要获得foo.prototype,我们首先尝试从prototype获取foo
  2. foo没有prototype属性。
  3. 查找原型链:foo [[Prototype]]在构建Foo.prototype时设置为foo。 (请记住,Foo.prototype是函数Bar。)
  4. prototype上查找Bar
  5. 成功! Bar.prototype已定义。将其用于foo.prototype
  6. 不出所料,Bar.prototype等于Bar.prototype
  7.   

    它在哪里解释了规范中的这种行为?

    • 15.3.5.2解释说prototype属性用作其构造对象的[[Prototype]]内部属性。

    • 13.2.2(步骤5 - 7)详细说明了上述15.3.5.2中描述的确切程序。

    • 8.6.2描述了基于原型的一般继承(即,如果某个对象没有属性,请查看其[[Prototype]]等)