为什么`constructor`指向下面的Object?

时间:2016-10-20 02:41:14

标签: javascript constructor prototype javascript-objects

我读到,只要定义了对象文字,就不会调用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指向对象。

2 个答案:

答案 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
});