继承的另一种方式(除了使用call)


我们来详细看一下这些定义。这是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 会按以下步骤执行:

  1. new 操作符创建了一个新的通用对象,并将其 __proto__ 属性设置为 Engineer.prototype
  2. new 操作符将该新对象作为 this 的值传递给 Engineer 构造器。
  3. 构造器为该新对象创建了一个名为 base 的新属性,并指向 WorkerBee 的构造器。这使得 WorkerBee 构造器成为 Engineer 对象的一个方法。base 属性的名称并没有什么特殊性,我们可以使用任何其他合法的名称来代替;base 仅仅是为了贴近它的用意。
  4. 构造器调用 base 方法,将传递给该构造器的参数中的两个,作为参数传递给 base 方法,同时还传递一个字符串参数  "engineering"。显式地在构造器中使用 "engineering" 表明所有 Engineer 对象继承的 dept 属性具有相同的值,且该值重载了继承自 Employee 的值。

  5. 因为 baseEngineer 的一个方法,在调用 base 时,JavaScript 将在步骤 1 中创建的对象绑定给 this 关键字。这样,WorkerBee 函数接着将 "Doe, Jane""engineering" 参数传递给 Employee 构造器函数。当从 Employee 构造器函数返回时,WorkerBee 函数用剩下的参数设置 projects 属性。

  6. 当从 base 方法返回后,Engineer 构造器将对象的 machine 属性初始化为 "belau"
  7. 当从构造器返回时,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";

扫描二维码关注公众号,回复: 1960753 查看本文章

现在 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 方法了。






猜你喜欢

转载自blog.csdn.net/weixin_38174062/article/details/80941389