省略prototype.constructor会更改原型链

时间:2015-06-05 15:04:26

标签: javascript constructor

我正在尝试理解JavaScript中的继承,我发现在JavaScript中有不同的方法来完成继承。其中一种方法是基于Mozilla网站的一个示例,该示例执行类似于以下代码的操作:

function Person(name) {
  this.name = name;
}

Person.prototype.getName = function() {
  return this.name;
}

Person.prototype.setName = function(name) {
  this.name = name;
}

function Employee(name, Id) {
  Person.call(this, name);
  this.Id = Id;
}

Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;

Employee.prototype.getId = function() {
  return this.Id;
}

Employee.prototype.setId = function(Id) {
  this.Id = Id;
}

var andrew = new Employee("Andrew", "123");

我知道这段代码非常基本,我真的不需要定义getter和setter。我只添加它们以表明我可以添加到每个原型对象。在大多数情况下,我理解这段代码的作用。

当我看到以下行

时,我开始感到困惑
Employee.prototype.constructor = Employee;

我知道我们正在设置Employee.prototype对象的构造函数属性以指向Employee构造函数。我已经阅读了这个网站的其他帖子,说我可以省略这一行,如果我这样做,一切都按预期工作。但是......当我省略这一行时,我看到了原型链的一些变化。现在,Employee对象的__proto__属性使用以下方法指向通用对象:getIdsetId。然后,此对象的__proto__属性指向Person.prototype对象。

所以我的问题是:

为什么当我省略Employee.prototype.constructor = Employee __proto__属性指向使用我在Employee.prototype对象中设置的方法而不是Employee.prototype对象的通用对象时本身?此外,getIdsetId方法如何附加到这个神秘的原型上,是否因此有任何性能影响?

我已经从Chrome控制台附加了console.logs,以便在手动设置构造函数属性时显示__proto__属性,然后省略它。

With Employee.prototype.constructor

Without Employee.prototype.constructor

3 个答案:

答案 0 :(得分:4)

对象没有名称。因此,您在__proto__旁边看到的是控制台以某种方式推断的名称。显然,这种方式涉及constructor

原型链不会改变,只会提供给您的信息。无论__proto__的价值如何,Employee.prototype都会引用constructor

看一下这个例子:

var foo = {};
console.log(foo); // Object {}

foo.constructor = function Foo() {};
console.log(foo); // Foo {}

foo在这里没有变化,这是一个普通的对象。但是,设置constructor后,它就会显示为Foo的实例。

答案 1 :(得分:2)

似乎Chrome只需constructor属性即可在控制台中显示对象的类名 因此可以创建任何对象并简单地将任何函数分配给它的constructor属性。结果 - 您将在控制台中看到此名称:

var obj = { prop: 1 };
obj.constructor = function MyName() {};

将显示:

enter image description here

答案 2 :(得分:2)

  

... __proto__属性指向一个通用对象,其中包含我在Employee.prototype对象中设置的方法,而不是Employee.prototype对象本身?

"通用对象"您正在谈论 Employee.prototype。您可以通过以下方式在Chrome中轻松测试:

  • 右键点击__proto__: Object
  • 选择" 存储为全局变量"从菜单中创建temp1变量
  • 测试temp1 == Employee.prototypetrue