寄生组合式继承

寄生组合式继承,从名字看就可以理解为寄生式继承和组合式继承的结合版,是开发人员普遍认为寄生组合式继承是引用类型最理想的继承范式。要了解寄生组合式继承首先从寄生式继承和组合式继承。

组合式继承

组合式继承将原型链和构造函数的技术组合到一起,结合两者的优点,通过原型链实现对原型属性和方法的继承以及借用构造函数来实现对实例属性的继承。拥有以下的优点

  1. 父类的方法可以被复用
  2. 父类的引用属性不会被共享
  3. 子类构建实例时可以向父类传递参数
    不过组合式继承中两次调用了父类构造函数,
// 创建父类
   let parent = function(name) {
      // 父类型的自有属性
      this.name = name;
      this.hobbies = ['tennis','music','photography']
   }
   // 添加父类方法
   parent.prototype = {
       getName() { console.log(this.name) }
   }
   // 创建子类
   let son = function(name,sex) {
      //构造函数式继承父类属性,这里是第二次调用父类构造函数
      parent.call(this, name); 
      // 添加子类自己的私有属性
      this.sex = sex;
   }
   // 这里是类式继承子类原型继承父类,是第一次调用父类构造函数
   son.prototype = new parent(); 
   // 将构造函数指向自己
   son.prototype.constructor = son;
   // 添加子类自己的方法
   son.prototype.getsex = function () { console.log(this.sex)}
   // 创建实例
   let sub1 = new son('taec','male')
   console.log(sub1)
   sub1.getName()
   sub1.getsex()


根据上面代码个人理解的原型链如下图所示,如果不对希望有大佬指正下
组合继承原型链

寄生式继承

创建一个封装基础过程的函数,该函数内部以某种方式来增强对象,最后再像真的是它做了所有工作一样返回对象。

   // 设置父类自有属性和方法
   let parent2 =  {
      name:'zy',
      hobbies:['tennis','music','photography'],
      getName:function () {console.log(this.name)}
   }
   // 这个方法用于创建一个新对象并且连接原型链
   function object (obj) {
     function F(){}
     F.prototype = obj;
     return new F (); 
   }
   function createson (o,sex) { 
     // 传入父类创建个新对象  
     let newson = object(o)
     // 这里增强对象,添加属性和方法
     newson.sex = sex
     newson.getsex = function () { console.log(this.sex) }
     // 返回对象
     return newson
   }  
   let sub2 = createson(parent2,'famle')
   console.log(sub2)
   sub2.getName()
   sub2.getsex()

寄生继承实现

根据上面的代码可以建立如下的原型链图,如果不对希望有大佬指正下

寄生式继承因为使用了一个函数以某种形式来增强对象,最后返回对象,那么复用率就不高,导致效率低。

寄生组合式继承

了解了组合继承和寄生继承之后就是寄生式组合继承了,它是通过借用构造函数来继承属性,通过原型链形式来继承方法,会解决2次调用父类函数以及复用率的问题。
这里使用《JavaScript高级程序设计》中的代码来解释继承的方法

   // 实现继承的核心函数
   function inheritPrototype(subType,superType) {
      function F() {};
      //F()的原型指向的是superType
      F.prototype = superType.prototype; 
      //subType的原型指向的是F()
      subType.prototype = new F(); 
      // 重新将构造函数指向自己,修正构造函数
      subType.prototype.constructor = subType; 
   }
   // 设置父类
   function SuperType(name) {
       this.name = name;
       this.colors = ["red", "blue", "green"];
       SuperType.prototype.sayName = function () {
         console.log(this.name)
       }
   }
   // 设置子类
   function SubType(name, age) {
       //构造函数式继承--子类构造函数中执行父类构造函数
       SuperType.call(this, name);
       this.age = age;
   }
   // 核心:因为是对父类原型的复制,所以不包含父类的构造函数,也就不会调用两次父类的构造函数造成浪费
   inheritPrototype(SubType, SuperType)
   // 添加子类私有方法
   SubType.prototype.sayAge = function () {
      console.log(this.age);
   }
   var instance = new SubType("Taec",18)
   console.dir(instance)

继承结果

可以看到很好的继承了父类的方法和属性以及自己添加属性和方法,并且只调用了1次父类构造函数,同时保证了原型链的完整,是一种理想的继承方法。下图是自己理解的图示,如果有错误希望大佬来指正
寄生组合继承

参考了一些文章:

  1. 一篇文章理解JS继承——原型链/构造函数/组合/原型式/寄生式/寄生组合/Class extends
  2. 寄生组合式继承
  3. 六种Js中常见的继承方式(图解)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 前面介绍的组合继承最大的问题就是无论什么情况下,都会调用两次父类型的构造函数:一次是在创建子类型原型的时候,另一次...
    赵者也阅读 2,675评论 0 0
  • 组合式继承: 组合继承的缺点:会调用两次父类型构造函数,在子类型的原型上创造了不必要的、多余的属性 寄生组合式继承...
    樱木夜访流川枫阅读 2,586评论 0 0
  • JS 继承(三)寄生组合式继承 JS 继承(二)中说了组合继承的模式,这种模式看起来似乎不错的样子,那么它有什么缺...
    IamaStupid阅读 3,987评论 0 0
  • JS的继承方式有很多种,最理想的继承方式是寄生组合式继承。组合继承(构造函数和原型的组合)会调用两次父类构造函数的...
    开始懂了_317阅读 12,169评论 0 4
  • 组合式继承的不足 组合继承是JavaScript最常用的继承模式,但也有它的不足: 无论什么情况下,都会调用两次超...
    potato865阅读 4,423评论 0 2

友情链接更多精彩内容