我们来详细看一下这些定义。这是Engineer
构造函数的新定义:
function Engineer (name, projs, mach) {
this.base = WorkerBee;
this.base(name, "engineering", projs);
this.machine = mach || "";
}
假设您创建了一个新的 Engineer
对象,如下所示:
var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
JavaScript 会按以下步骤执行:
new
操作符创建了一个新的通用对象,并将其__proto__
属性设置为Engineer.prototype
。new
操作符将该新对象作为this
的值传递给Engineer
构造器。- 构造器为该新对象创建了一个名为
base
的新属性,并指向WorkerBee
的构造器。这使得WorkerBee
构造器成为Engineer
对象的一个方法。base
属性的名称并没有什么特殊性,我们可以使用任何其他合法的名称来代替;base
仅仅是为了贴近它的用意。 -
构造器调用
base
方法,将传递给该构造器的参数中的两个,作为参数传递给base
方法,同时还传递一个字符串参数"engineering"。显式地在构造器中使用
"engineering"
表明所有Engineer
对象继承的dept
属性具有相同的值,且该值重载了继承自Employee
的值。 -
因为
base
是Engineer
的一个方法,在调用base
时,JavaScript 将在步骤 1 中创建的对象绑定给this
关键字。这样,WorkerBee
函数接着将"Doe, Jane"
和"engineering"
参数传递给Employee
构造器函数。当从Employee
构造器函数返回时,WorkerBee
函数用剩下的参数设置projects
属性。 - 当从
base
方法返回后,Engineer
构造器将对象的machine
属性初始化为"belau"
。 - 当从构造器返回时,JavaScript 将新对象赋值给
jane
变量。
你可以认为,在 Engineer
的构造器中调用了 WorkerBee
的构造器,也就为 Engineer
对象设置好了继承关系。事实并非如此。调用 WorkerBee
构造器确保了Engineer
对象以所有在构造器中所指定的属性被调用。但是,如果后续在 Employee
或者 WorkerBee
原型中添加了属性,那些属性不会被 Engineer
对象继承。例如,假设如下语句:
function Engineer (name, projs, mach) {
this.base = WorkerBee;
this.base(name, "engineering", projs);
this.machine = mach || "";
}
var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
Employee.prototype.specialty = "none";
对象 jane
不会继承 specialty
属性。您必须显式地设置原型才能确保动态的继承。如果修改成如下的语句:
function Engineer (name, projs, mach) {
this.base = WorkerBee;
this.base(name, "engineering", projs);
this.machine = mach || "";
}
Engineer.prototype = new WorkerBee;
var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
Employee.prototype.specialty = "none";
现在 jane
对象的 specialty
属性为 "none" 了。
继承的另一种途径是使用call()
/ apply()
方法。下面的方式都是等价的:
function Engineer (name, projs, mach) {
this.base = WorkerBee;
this.base(name, "engineering", projs);
this.machine = mach || "";
}
function Engineer (name, projs, mach) {
WorkerBee.call(this, name, "engineering", projs);
this.machine = mach || "";
}
使用 javascript 的 call()
方法相对明了一些,因为无需 base
方法了。