省略 prototype.constructor 更改原型链
Omitting prototype.constructor changes prototype chain
我试图了解 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__
属性 现在指向具有以下方法的通用对象:getId
和 setId
。然后这个对象的__proto__
属性指向Person.prototype
对象。
所以我的问题是:
为什么当我省略 Employee.prototype.constructor = Employee
时,__proto__
属性 指向一个具有我在 Employee.prototype
对象中设置的方法的通用对象,而不是Employee.prototype
对象本身?此外,getId
和 setId
方法是如何附加到这个神秘的原型上的,是否会因此影响性能?
我已经从 Chrome 控制台附加了 console.logs 以显示 __proto__
属性 手动设置构造函数 属性 然后省略它.
对象没有名字。因此,您在 __proto__
旁边看到的是控制台 以某种方式 推断出的名称。显然,这种方式涉及 constructor
某种方式。
原型链没有变化,只是呈现给您的信息。 __proto__
指的是 Employee.prototype
而不管 constructor
的值。
看看这个例子:
var foo = {};
console.log(foo); // Object {}
foo.constructor = function Foo() {};
console.log(foo); // Foo {}
foo
这里没有变化,是一个普通的对象。但是,一旦 constructor
被设置,它就好像是 Foo
.
的一个实例一样呈现
似乎 Chrome 只需要 constructor
属性 即可在控制台中显示对象的 Class 名称。
因此可以创建任何对象并简单地为其分配任何函数 constructor
属性。结果 - 您将在控制台中看到此名称:
var obj = { prop: 1 };
obj.constructor = function MyName() {};
将显示:
...the __proto__
property points to an generic object with the methods I set in the Employee.prototype
object and not the Employee.prototype
object itself?
你说的"generic object"是Employee.prototype
。您可以自己在 Chrome 中通过以下方式轻松测试:
- 右键单击
__proto__: Object
行
- 从菜单中选择“存储为全局变量”以创建
temp1
变量
- 测试
temp1 == Employee.prototype
是 true
我试图了解 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__
属性 现在指向具有以下方法的通用对象:getId
和 setId
。然后这个对象的__proto__
属性指向Person.prototype
对象。
所以我的问题是:
为什么当我省略 Employee.prototype.constructor = Employee
时,__proto__
属性 指向一个具有我在 Employee.prototype
对象中设置的方法的通用对象,而不是Employee.prototype
对象本身?此外,getId
和 setId
方法是如何附加到这个神秘的原型上的,是否会因此影响性能?
我已经从 Chrome 控制台附加了 console.logs 以显示 __proto__
属性 手动设置构造函数 属性 然后省略它.
对象没有名字。因此,您在 __proto__
旁边看到的是控制台 以某种方式 推断出的名称。显然,这种方式涉及 constructor
某种方式。
原型链没有变化,只是呈现给您的信息。 __proto__
指的是 Employee.prototype
而不管 constructor
的值。
看看这个例子:
var foo = {};
console.log(foo); // Object {}
foo.constructor = function Foo() {};
console.log(foo); // Foo {}
foo
这里没有变化,是一个普通的对象。但是,一旦 constructor
被设置,它就好像是 Foo
.
似乎 Chrome 只需要 constructor
属性 即可在控制台中显示对象的 Class 名称。
因此可以创建任何对象并简单地为其分配任何函数 constructor
属性。结果 - 您将在控制台中看到此名称:
var obj = { prop: 1 };
obj.constructor = function MyName() {};
将显示:
...the
__proto__
property points to an generic object with the methods I set in theEmployee.prototype
object and not theEmployee.prototype
object itself?
你说的"generic object"是Employee.prototype
。您可以自己在 Chrome 中通过以下方式轻松测试:
- 右键单击
__proto__: Object
行 - 从菜单中选择“存储为全局变量”以创建
temp1
变量 - 测试
temp1 == Employee.prototype
是true