New JavaScript prototype changes constructor

扶醉桌前 提交于 2019-12-13 19:46:34

问题


When you create an object with a constructor it has a constructor property pointing to the constructor function:

var Foo = function(foo) {
    this.foo = foo;
}
var myFoo = new Foo(123);
myFoo.constructor === Foo; // true

After creating this object I can change Foo.prototype ...

Foo.prototype.x = 'y';

... or reassign a new prototype object:

Foo.prototype = {
    num: 99
};
myFoo.constructor === Foo; // still true

But if I create a new Foo object after assigning a new object to Foo.prototype its constructor suddenly points to Object:

var myBar = new Foo(321);
myBar.constructor === Foo; // false
myBar.constructor === Object; // wtf?!

Adding new properties to the prototype doesn't produce this effect, you have to do the assignment Foo.prototype = {...}.

I have no idea why creating a new prototype would affect the constructor property. I tested in Chrome, Firefox and Internet Explorer, all with the same result. Can anybody help me understand this?


回答1:


The constructor property of any object is inherited from that object's prototype.

The default prototype object created with any function contains a constructor property that refers to that function, as detailed in the spec.

Your new prototype object doesn't have that constructor property, and instead has its own constructor property inherited from Object.prototype.




回答2:


To sum it up:

  • myFoo.constructor is in fact myFoo.__proto__.constructor.
  • Creating a new prototype doesn't affect existing objects. In the example above, myFoo.x has the value "y" but myFoo.num is undefined.
  • Newly created objects use that new prototype, of course, which has no property constructor. Therefore they inherit it. In the example above, myBar.constructor is in fact myBar.__proto__.__proto__.constructor which points to Object.

If you assign a new prototype from an object literal you simply can set a constructor property:

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

Or, more precisely:

Foo.prototype = {
    num: 99
};
Object.defineProperty(Foo.prototype, "constructor", {
    writable: true,
    configurable: true,
    enumerable: false,
    value: Foo
});


来源:https://stackoverflow.com/questions/24335642/new-javascript-prototype-changes-constructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!