我试图理解这段代码并且想知道为什么我们在子“类”构造函数中调用 super 构造函数:
function Person(name) {
this.name = name;
}
// Other properties on Person prototype here...
function Employee(id, name) {
Person.call(this, name); // Why do we have to do this?
this.id = id;
}
Employee.prototype = Object.create(Person.prototype);
// Other properties on Employee prototype here...
1) 为什么我们有 Person.call(this, name)
?在“Javascript Ninja 的 secret ”中,他们执行 prototype
继承 WITHOUT 调用 super 构造函数(其余代码相同,除了 Object.create
,但我明白为什么需要这样做)。
最佳答案
所以这是没有 Person.call(this,name)
行的 Employee(和 Person)的原型(prototype)链:
|Person| |Employee|
|------| |--------|
|name | |wage |
|sex | |id |
| |
| |
v v
|Person Prototype| |Employee Prototype|
|----------------| |------------------|
|walk() | <-------- |work() |
|eat() | |goOnStrike() |
|sleep() |
|
|
v
|Object|
|------|
| *** |
每次您请求员工的属性时,JavaScript 都会沿着原型(prototype)链查找该属性。如果你这样写:
var employee = new Employee(1, "Jack White");
employee.walk();
JavaScript 将在 employee
中查找,然后在 employee.[[prototype]]
中查找,然后在 employee.[[prototype]].[[prototype] 中查找]
(按照图中的箭头方向)直到找到属性 walk
。
如您所见,如果您请求属性name
,JavaScript 将找不到它,因为它不在employee
的原型(prototype)链中。因此,您必须确保还“复制”本地属性,例如 name
和 sex
。
您可以通过使用当前 Employee
的上下文调用 Person
的构造函数来执行此操作:
function Employee(id, name) {
Person.call(this, name);
this.id = id;
}
这与您只是将 Person 构造函数内部的所有代码复制到 Employee 构造函数中基本相同:
function Employee(id, name) {
this.name = name; //copied from Person
this.id = id;
}
这导致以下设置和一个具有 name 属性的员工:
|Person| |Employee|
|------| |--------|
|name | |wage |
|sex | |id |
|name |
|sex |
| |
| |
v v
|Person Prototype| |Employee Prototype|
|----------------| |------------------|
|walk() | <-------- |work() |
|eat() | |goOnStrike() |
|sleep() |
|
|
v
|Object|
|------|
| *** |
关于javascript - 原型(prototype)继承 : Calling super constructor in sub "class" constructor function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21092798/