原型和对象创建

时间:2011-09-28 16:02:40

标签: javascript inheritance object prototype-programming

最近我正试图获得原型链的技术方面。现在我有一些关于对象实例化的问题。

请考虑以下代码:

var Foo = function(s) {
  this._bar = s;
};

var fooInst = new Foo('test');

现在,当我检查创建的对象时,然后:

Foo.prototype === Function.prototype; // true

fooInst.prototype === ?
fooInst.prototype.prototype === Object.prototype; // true

我想知道,fooInst.prototype究竟是什么。在Chromes检查员中,它似乎是某种具有Foo属性的constructor。但是我读到的有关原型的所有资料都表明fooInst.prototype === Foo.prototype应该是真的。

所以我的问题是:JS如何处理原型链。当我致电new Foo时会发生什么。

提前致谢!

修改

所以我发现,(在Chrome中)Object.getPrototypeOf(fooInst) === Foo.prototype;true,但Object.getPrototypeOf(fooInst) === Object.getPrototypeOf(Foo)false。为什么?

3 个答案:

答案 0 :(得分:6)

  

我想知道fooInst.prototype究竟是什么。

undefined

fooInst.prototype === undefined; // true

只有函数具有自动.prototype属性。物体没有。

如果使用构造函数创建对象,例如:

var fooInst = new Foo('test');

...然后fooInst会有Foo.prototype的内部引用,但没有标准属性可以从Foo.prototype获取fooInst


也就是说,某些 JavaScript环境支持非标准属性,用于引用原型对象。

fooInst.__proto__ === Foo.prototype; // true (if __proto__ supported)

此外,还可以使用 ECMAScript 5 提供的方法

Object.getPrototypeOf( fooInst ) === Foo.prototype;  // true

从对象到其原型对象的内部引用可能只是这类引用链中的第一个引用。

原型对象可能有自己的原型对象被引用。 (在基本情况下,这将是Object.prototype,或者使用更长的链,Object.prototype可能会在链的下方。)

Object.prototype本身引用null作为其原型。这就结束了链条。

您应该注意,如果更改构造函数的.prototype对象,则从对象到其原型对象的内部引用不会更改。它是对象生命中存在的参考。

var Foo = function(s) {
  this._bar = s;
};

var fooInst = new Foo('test');

Object.getPrototypeOf( fooInst ) === Foo.prototype;  // true

// Change the prototype object of Foo
Foo.prototype = { some:'object' };

Object.getPrototypeOf( fooInst ) === Foo.prototype;  // false

答案 1 :(得分:2)

你的第一个假设:

Foo.prototype === Function.prototype;

不对,我认为你正在混淆所有对象所具有的[[Prototype]]内部属性的概念,并使原型链的“链接”和功能的prototype属性混合起来对象有。

上述比较将产生false,因为Foo.prototype属性的值是在创建Foo函数时创建的新对象。

每当您创建一个函数对象时,都会初始化此对象,它继承自Object.prototype并且它有一个名为constructor的属性,该属性指向函数(Foo.prototype.constructor === Foo),它是在将函数作为构造函数调用时使用。

现在,如果我们谈论[[Prototype]]内部属性,那么您的[[Prototype]]函数的Foo就是Function.prototype,换句话说,Foo }继承自Function.prototype,例如:

Object.getPrototypeOf(Foo) === Function.prototype; // true
Foo instanceof Function; // true
Foo.__proto__ === Function.prototype; // true

关于fooInst此对象是在新表达式中创建的,当您使用Foo函数作为构造函数时,会生成此新对象,并且它继承自{ {1}},(其内部Foo.prototype属性指向[[Prototype]])。

它没有Foo.prototype属性,因为此属性仅对函数对象有意义。

另见:

答案 2 :(得分:1)

您可能会在JavaScript. The Core中找到解释和图表。

所有对象都有原型链。因此,fooInst有一个原型链,其头部为Foo.prototype。当您调用new Foo时,创建了一个Object,Foo.prototype被设置为其原型链,并且在新Object的上下文中调用了构造函数。

有些浏览器将此公开为非标准 __proto__属性,例如:

fooInst.__proto__ === Foo.prototype