问题
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.constructoris in factmyFoo.__proto__.constructor.- Creating a new prototype doesn't affect existing objects. In the example above,
myFoo.xhas the value"y"butmyFoo.numisundefined. - Newly created objects use that new prototype, of course, which has no property
constructor. Therefore they inherit it. In the example above,myBar.constructoris in factmyBar.__proto__.__proto__.constructorwhich points toObject.
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