理解函数原型和__proto__

时间:2016-04-10 11:40:04

标签: javascript

我对函数的原型有疑问,也许有点不寻常,请参阅此代码并注意代表控制台输出的注释:

function Foo () {
};

var o = Foo.prototype;

console.log(o.__proto__); // Object {}
console.log(o.constructor); // function Foo() {}
console.log(o.__proto__.constructor); // function Object() { [native code] }

console.log(o.__proto__.constructor === o.constructor); // false

请忽略我使用__proto__而不是标准getPrototypeOf()

我试图弄清楚为什么最后一行打印出false。我们通常知道,对于任何对象,以下都是正确的:

obj.__proto__.constructor === obj.constructor

期待理解为什么这不是o以上o的情况,因为o也是一个对象。

我想知道它是否是假的,因为Foo.prototype实际上是一个函数的原型实例(o.constructor),因此在Foo设置期间Foo设置为{{1}} 。

我知道这可能没什么实用价值,但了解一些事情很有用。

1 个答案:

答案 0 :(得分:3)

这不是一个不变量:

Object.getPrototypeOf(obj).constructor === obj.constructor

相反,通常人们不会向其对象添加自定义constructor属性,并且大多数对象不是构造函数的prototype对象。因此,当您访问constructor属性时,您将获得从[[Prototype]]继承的值(如果有)。

function Foo(){}
Foo.prototype.constructor; // Foo (own property)
new Foo().constructor; // Foo (inherited from Foo.prototype)

但是,构造函数的prototype对象默认具有自己的constructor属性,通常与[[Prototype]]的constructor不同(如果有的话)。

function Foo(){}
Foo.prototype.constructor; // Foo (own property)
var proto = Object.getPrototypeOf(Foo.prototype); // Object.prototype
proto.constructor; // Object (own property of proto/Object.prototype)

请记住constructor没有什么特别之处,它只是一个普通的属性,它是在构造函数的prototype对象中自动创建的,以帮助您从实例中获取构造函数。但是你可以修改,删除或遮蔽它。