我读到,只要定义了对象文字,就不会调用Object构造函数:
var ob1 = new Object(); // constructor called
var ob2 = {}; // constructor never called
现在考虑以下事项:
// a constructor
function Animal (name, food) {
// definition of constructor
}
Animal.prototype = {
// some properties in the prototype
// but `constructor` is not set back to Animal
}
在上面的代码中,因为我完全覆盖了原型,所以constructot
设置为指向Object
。如果我没有错,那么构造函数属性设置为指向调用时的构造函数,从而导致创建原型。我的问题是,虽然我完全重新定义了原型,但是没有调用Object构造函数(因为它只是一个对象文字)。那么为什么constructor
指向对象。
答案 0 :(得分:1)
为什么
constructor
指向对象。
该属性及其值继承自Object.prototype
。
Animal.prototype.constructor === Object.prototype.constructor; // true
由于Animal.prototype
是一个从文字/初始值设定项创建的对象实例,因此它继承了Object.prototype
的所有属性,包括其constructor
。
constructor
属性通常在原型对象上分配,并由实例继承。
引擎为您设置了很多,但只有在定义新功能时才设置一次。
function Animal() {}
console.log(Animal.prototype.constructor); // function Animal() {}
完全替换prototype
后,自动分配不会保留。
Animal.prototype = {};
console.log(Animal.prototype.constructor); // function Object() {}
constructor
属性也只是提供信息。正如您所发现的那样,它实际上并不能保证其准确性,因为它很容易被改变或覆盖。
并且,调用构造函数不会自动为新实例分配constructor
属性的值。至少,除非你定义明确的功能:
function Animal() {
this.constructor = Animal;
}
Animal.prototype = {};
console.log(new Animal().constructor); // function Animal() { ... }
否则,由于修改后的Animal.prototype
没有指定自己的constructor
...
Animal.prototype.hasOwnProperty('constructor'); // false
它从自己的原型继承了该值:
Object.getPrototypeOf(Animal.prototype) === Object.prototype; // true
Object.prototype.hasOwnProperty('constructor'); // true
Object.prototype.constructor; // function Object() { }
答案 1 :(得分:1)
当你替换构造函数的原型时,你应该总是重置构造函数属性:
Animal.prototype = {
constructor: Animal
// some properties in the prototype
};
或者,可以说,你不应该替换原型,只是扩展原型:
Object.assign(Animal.prototype, {
// some properties in the prototype
});