javascript继承只有一种实现方式

只做总结,具体概念可以看我引用的博客文章。
引用:阮一峰博客

为什么我说只有一种继承,那就是原型链继承。实现方式虽然多,但本质只有这一种。
结论在第五条总结部分。

1. 空对象中介继承(函数类型+原型链方式)

优点:

  • 空对象不占内存
  • 修改子对象的constructor不会改变父对象的constructor
  • 我认为es6中extend的实现方式

实现:

function extend(child,parent){
    // parent.apply(child); 不能在这里加,不然this.type就是child的静态方法了

    var f = function(){}
    f.prototype = parent.prototype;
    child.prototype = new f();
    child.prototype.constructor = child;  // 注意:默认指向parent,这里改成自己
    child.uber = parent.prototype; // 备用属性
}

小栗子一号:

var cat = function(name){
    this.name = name;
    this.type = 'dongwu'
}

cat.prototype.getName = function(){
    console.log(`this name is: ${this.name}`)
}

cat.prototype.getType = function(){
    console.log(`this type is: ${this.type}`)
}

var catFood = function(user, name){
    cat.apply(this)
    this.user = user;
    this.name = name;
}

extend(catFood, cat);

catFood.prototype.getUser = function(){
    console.log(`this user is: ${this.user}`)
}

console.log(catFood instanceof cat) //false
console.log(catFood.uber === cat.prototype) //uber属性的使用。
var foot = new catFood('maoliang', 'maomi')
foot.getName();
foot.getUser();
foot.getType();
console.log(foot instanceof catFood) //true
console.log(foot instanceof cat) //true

2.拷贝继承(函数类型+原型链拷贝方式)

优缺点:
 我觉得还不如第一种空值继承法呢,破坏了原型链继承。

实现如下:

function extend(child,parent){
    var c = child.prototype;
    var p = parent.prototype;
    for(var i in p){ // 使用for in来枚举所有属性(可枚举和不可枚举)
        c[i] = p[i]
    }
    child.uber = parent.prototype;
}

3.非构造函数继承(对象类型+原型链方式)

优缺点:
   主要是针对object类型, 且不支持复合类型,比如对象之类。
   这也是Object.create()函数的伪代码

小栗子二号:

var extent = function(parent){
    var f = function(){}
    f.prototype = parent;
    return new f();
}

var father = {
    isfather: 'yes'
}

var son = extent(father);
console.log(son.__proto__ === father) // true

son.isSon = 'yes'
console.log(son.isfather) //yes
console.log(son.isSon) //yes

4. 不用prototype链的深拷贝继承(对象类型+拷贝方式)

优缺点:
  jquery的实现方式

实现:

function extendCopy(p, c) {
  var c = c || {};
  for (var i in p) {
    if (typeof p[i] === 'object') {
      c[i] = Array.isArray(p[i]) ? [] : {};
      extendCopy(p[i], c[i])
    } else {
      c[i] = p[i];
    }
  }
  return c;
}

小栗子三号:

var Chinese = {
  nation: '中国',
  birthPlaces: ['北京', '上海', '香港']
};

var Doctor = extendCopy(Chinese);
Doctor.birthPlaces.push('厦门');

console.log(Doctor.nation); // 中国
console.log(Doctor.birthPlaces); //北京, 上海, 香港, 厦门
console.log(Chinese.birthPlaces); //北京, 上海, 香港

5.总结(重点)

  • 虽然上面有四种实现方式,但我认为,继承是针对函数的,毕竟根据instanceof的定义来说,对象是没有prototype的。
  • 所以,继承只有一种就是函数的原型链继承(原型链拷贝方式破坏了继承,不能算数)。
  • 而,对象可以有原型链和拷贝两种“继承”, 原型链的方式是Object.create的实现,拷贝是jquery的实现。
  • 在jquery的实现中,并没有对函数做拷贝,具体源码详解可参考:文章
  • 我认为YUI库的消失,可能和es5、es6有关,es5和es6可能借鉴了YUI库的一些代码。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值