最近我正试图获得原型链的技术方面。现在我有一些关于对象实例化的问题。
请考虑以下代码:
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
。为什么?
答案 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