使用构造函数创建对象时,它具有指向构造函数的constructor
属性:
var Foo = function(foo) {
this.foo = foo;
}
var myFoo = new Foo(123);
myFoo.constructor === Foo; // true
创建此对象后,我可以更改Foo.prototype
...
Foo.prototype.x = 'y';
...或重新分配一个新的原型对象:
Foo.prototype = {
num: 99
};
myFoo.constructor === Foo; // still true
但是如果我在将新对象分配给Foo.prototype
之后创建一个新的Foo对象,它的构造函数会突然指向Object
:
var myBar = new Foo(321);
myBar.constructor === Foo; // false
myBar.constructor === Object; // wtf?!
向原型添加新属性不会产生此效果,您必须执行作业Foo.prototype = {...}
。
我不知道为什么创建新原型会影响构造函数属性。我在Chrome,Firefox和Internet Explorer中测试过,结果相同。有人能帮我理解吗?
答案 0 :(得分:1)
任何对象的constructor
属性都是从该对象的原型继承的。
使用任何函数创建的默认prototype
对象包含引用该函数的constructor
属性,详见spec。
您的新prototype
对象没有该constructor
属性,而是拥有自constructor
继承自Object.prototype
的{{1}}属性。
答案 1 :(得分:0)
总结一下:
myFoo.constructor
实际上是myFoo.__proto__.constructor
。myFoo.x
的值为"y"
,但myFoo.num
为undefined
。constructor
。因此他们继承了它。在上面的示例中,myBar.constructor
实际上是myBar.__proto__.__proto__.constructor
,指向Object
。如果从对象文字中分配新原型,则只需设置构造函数属性:
var Foo = function(foo) {
this.foo = foo;
};
var myFoo = new Foo(123);
Foo.prototype = {
num: 99,
constructor: Foo
};
var myBar = new Foo(99);
myBar.constructor === myFoo.constructor; // true
或者更准确地说:
Foo.prototype = {
num: 99
};
Object.defineProperty(Foo.prototype, "constructor", {
writable: true,
configurable: true,
enumerable: false,
value: Foo
});