JavaScript继承(五)——寄生式继承

首先回顾一下原型式继承:

function object(obj){
  function F(){}
  f.prototype = obj;
  return new F();
}

寄生式继承是与原型式继承紧密相关的一种思路,并且同样也是由克罗克福德推而广之的。

说到寄生式继承不得不说工厂模式和寄生构造函数模式创建对象。下面来回顾一下工厂模式创建对象:

function createPerson(name, age, job){
  let o = new Object();
  o.name = name;
  o.age = age;
  o.job = job;
  o.sayName = function(){
    console.log(this.name);
  }
  return o;
}

let p = createPerson('bob', 18, 'JavaScript');
p.sayName();//bob

在函数体内创建了一个对象,然后对这个对象进行增强,添加一些属性和方法,再返回这个对象,使用时直接调用createPerson,并将参数传给它,就得到了我们想要的对象,但本质上 createPerson不过是封装了用于增强o的代码。

再看寄生构造函数模式创建对象:

function Person(name, age, job){
  let o = new Object();
  o.name = name;
  o.age = age;
  o.job = job;
  o.sayName = function(){
    console.log(this.name);
  }
  return o;
}

let p = new Person('bob', 18, 'JavaScript');
p.sayName();//bob

思路其实和工厂模式一样,只不过创建对象是通过new关键字进行的,而工厂模式是直接调用。

寄生式继承的思路就是类似上面这样:创建一个用于封装继承过程的函数,该函数内部以某种方式来增强对象,然后返回这个对象,该对象就是原对象的一个子对象。来看下面的示例:

function extend(obj){
  let child = object(obj);//或者使用Object.create(obj);
  child.sayHi = function(){
    console.log('hi');
  }
  return child;
}

创建extend函数,接收的参数就是将要继承的对象。函数体内使用object函数返回了obj的子对象child,然后通过给child添加sayHi方法,对child进行了增强,最后返回child。与原型式继承相比,寄生式继承帮我们封装了增强的代码,而原型式继承需要我们手动书写增强的代码。来看下面的示例:

let p = {
  name: 'bob',
  friends: ['jack', 'rose']
}

//使用寄生式继承
let p2 = extend(p);
p2.sayHi();//hi

//使用原型式继承
let p3 = object(p);
p3.sayHi = function(){
  console.log('hi');
}
p3.sayHi();//hi

JavaScript继承(四)——原型式继承中提到的Object.create方法,其可以接受一个或两个参数,接收一个参数时等同于object函数,也就是原型式继承,其实接收两个参数就等同于寄生式继承。来看下面的示例:

let p4 = Object.create(p, {
  sayHi: {
    value: function(){
       console.log('hi');
    }
  }
});
p4.sayHi();//hi

所以无论是原型式继承还是寄生式继承,使用Object.create就够了。

实际上,寄生式继承基本上可以替代原型式继承,寄生式继承可以看作原型式继承的增强。需要注意的是使用寄生式继承来为对象添加函数,会由于不能做到函数复用而降低效率,这一点与构造函数模式类似。关于构造函数模式,如下所示:

function Person(name, age, job){
  this.name = name;
  this.age = age;
  this.job = job;
  this.sayName = function(){
    alert(this.name);
  }
}
let p1 = new Person('zhangsan', 18, 'JavaScript');
let p2 = new Person('lisi', 20, 'Java');

可以参考这篇文章--JavaScript创建对象(二)——构造函数模式

转载于:https://my.oschina.net/bob1900/blog/3009443

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值