继承的另一种方式(除了使用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";

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






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值