__proto__
实际上,你可以用__proto__
访问对象的内部[[Prototype]]
财产。在继承层次结构中,您可以将[[Prototype]]
视为当前对象的实际父项。
prototype
这是一个特殊性质,(构造)函数对象,用于建立从所述构造函数创建的实例继承链上设置时。例如,
function Foo() {}
Foo.prototype = {a: 1};
现在,当您创建Foo
类型的新对象,新创建的对象的内部[[Prototype]]
属性将参考该Foo.prototype
对象。您可以确认这样
console.assert((new Foo()).__proto__ === Foo.prototype);
在你的情况,
myFunc.prototype = myObj;
正在创建的函数对象的prototype
属性,当你创建新的对象,这将只用于这个函数(构造函数)。您可能想将其视为新对象的模板。所以,当你做myFunc.a
时,JS引擎试图在myFunc
及其父母的原型链中找到a
,并且它没有找到它,这就是为什么它返回undefined
。
但是,当你做
myFunc.__proto__ = myObj;
您设置的myFunc
父,在原型链,myObj
。所以,当你做myFunc.a
时,JS引擎首先试图在myFunc
对象本身中找到a
,并且它不在那里。所以,它试图在其直接父母中找到它,即myObj
。这就是为什么它在这种情况下返回1
。
注:您可以使用下面的函数来理解原型链更好
function printPrototypeChain(object) {
while (object !== null) {
console.log(object);
object = Object.getPrototypeOf(object);
}
}
现在,让我们打印的原型链当对象被设置为功能的prototype
财产目的。
function myFunc() {}
myFunc.prototype = {
a: 1,
b: 2
};
printPrototypeChain(myFunc);
的输出将是
[Function: myFunc]
[Function: Empty]
{}
无这些对象具有限定a
,所以返回undefined
。但是,在这种情况下,
function myFunc() {}
myFunc.__proto__ = {
a: 1,
b: 2
};
printPrototypeChain(myFunc);
原型链变成这样
[Function: myFunc]
{ a: 1, b: 2 }
{}
和a
在myFunc
的直接父被发现。因此,返回相应的值1
。
注意:不要在您的实际代码中使用__proto__
,因为它保留在最新版本的JavaScript规范中,仅用于向后兼容。详细了解它here。改为使用Object.getPrototypeOf
和Object.setPrototypeOf
。
http://es5.github.io/完全不了解'__proto__'。这意味着它不是标准的一部分,你不应该使用它。 – zerkms
不,对象的原型(带有它的那个继承自)不是**'.prototype'。你读过所有的答案http://stackoverflow.com/questions/9959727/proto-vs-prototype-in-javascript?你不明白什么(我们很乐意改进它们)? – Bergi
那么什么是.prototype用于? – Flake