寄生組合式繼承

寄生組合式繼承,從名字看就可以理解為寄生式繼承和組合式繼承的結(jié)合版,是開發(fā)人員普遍認為寄生組合式繼承是引用類型最理想的繼承范式。要了解寄生組合式繼承首先從寄生式繼承和組合式繼承。

組合式繼承

組合式繼承將原型鏈和構(gòu)造函數(shù)的技術(shù)組合到一起,結(jié)合兩者的優(yōu)點,通過原型鏈實現(xiàn)對原型屬性和方法的繼承以及借用構(gòu)造函數(shù)來實現(xiàn)對實例屬性的繼承。擁有以下的優(yōu)點

  1. 父類的方法可以被復(fù)用
  2. 父類的引用屬性不會被共享
  3. 子類構(gòu)建實例時可以向父類傳遞參數(shù)
    不過組合式繼承中兩次調(diào)用了父類構(gòu)造函數(shù),
// 創(chuàng)建父類
   let parent = function(name) {
      // 父類型的自有屬性
      this.name = name;
      this.hobbies = ['tennis','music','photography']
   }
   // 添加父類方法
   parent.prototype = {
       getName() { console.log(this.name) }
   }
   // 創(chuàng)建子類
   let son = function(name,sex) {
      //構(gòu)造函數(shù)式繼承父類屬性,這里是第二次調(diào)用父類構(gòu)造函數(shù)
      parent.call(this, name); 
      // 添加子類自己的私有屬性
      this.sex = sex;
   }
   // 這里是類式繼承子類原型繼承父類,是第一次調(diào)用父類構(gòu)造函數(shù)
   son.prototype = new parent(); 
   // 將構(gòu)造函數(shù)指向自己
   son.prototype.constructor = son;
   // 添加子類自己的方法
   son.prototype.getsex = function () { console.log(this.sex)}
   // 創(chuàng)建實例
   let sub1 = new son('taec','male')
   console.log(sub1)
   sub1.getName()
   sub1.getsex()


根據(jù)上面代碼個人理解的原型鏈如下圖所示,如果不對希望有大佬指正下
組合繼承原型鏈

寄生式繼承

創(chuàng)建一個封裝基礎(chǔ)過程的函數(shù),該函數(shù)內(nèi)部以某種方式來增強對象,最后再像真的是它做了所有工作一樣返回對象。

   // 設(shè)置父類自有屬性和方法
   let parent2 =  {
      name:'zy',
      hobbies:['tennis','music','photography'],
      getName:function () {console.log(this.name)}
   }
   // 這個方法用于創(chuàng)建一個新對象并且連接原型鏈
   function object (obj) {
     function F(){}
     F.prototype = obj;
     return new F (); 
   }
   function createson (o,sex) { 
     // 傳入父類創(chuàng)建個新對象  
     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()

寄生繼承實現(xiàn)

根據(jù)上面的代碼可以建立如下的原型鏈圖,如果不對希望有大佬指正下

寄生式繼承因為使用了一個函數(shù)以某種形式來增強對象,最后返回對象,那么復(fù)用率就不高,導(dǎo)致效率低。

寄生組合式繼承

了解了組合繼承和寄生繼承之后就是寄生式組合繼承了,它是通過借用構(gòu)造函數(shù)來繼承屬性,通過原型鏈形式來繼承方法,會解決2次調(diào)用父類函數(shù)以及復(fù)用率的問題。
這里使用《JavaScript高級程序設(shè)計》中的代碼來解釋繼承的方法

   // 實現(xiàn)繼承的核心函數(shù)
   function inheritPrototype(subType,superType) {
      function F() {};
      //F()的原型指向的是superType
      F.prototype = superType.prototype; 
      //subType的原型指向的是F()
      subType.prototype = new F(); 
      // 重新將構(gòu)造函數(shù)指向自己,修正構(gòu)造函數(shù)
      subType.prototype.constructor = subType; 
   }
   // 設(shè)置父類
   function SuperType(name) {
       this.name = name;
       this.colors = ["red", "blue", "green"];
       SuperType.prototype.sayName = function () {
         console.log(this.name)
       }
   }
   // 設(shè)置子類
   function SubType(name, age) {
       //構(gòu)造函數(shù)式繼承--子類構(gòu)造函數(shù)中執(zhí)行父類構(gòu)造函數(shù)
       SuperType.call(this, name);
       this.age = age;
   }
   // 核心:因為是對父類原型的復(fù)制,所以不包含父類的構(gòu)造函數(shù),也就不會調(diào)用兩次父類的構(gòu)造函數(shù)造成浪費
   inheritPrototype(SubType, SuperType)
   // 添加子類私有方法
   SubType.prototype.sayAge = function () {
      console.log(this.age);
   }
   var instance = new SubType("Taec",18)
   console.dir(instance)

繼承結(jié)果

可以看到很好的繼承了父類的方法和屬性以及自己添加屬性和方法,并且只調(diào)用了1次父類構(gòu)造函數(shù),同時保證了原型鏈的完整,是一種理想的繼承方法。下圖是自己理解的圖示,如果有錯誤希望大佬來指正
寄生組合繼承

參考了一些文章:

  1. 一篇文章理解JS繼承——原型鏈/構(gòu)造函數(shù)/組合/原型式/寄生式/寄生組合/Class extends
  2. 寄生組合式繼承
  3. 六種Js中常見的繼承方式(圖解)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前面介紹的組合繼承最大的問題就是無論什么情況下,都會調(diào)用兩次父類型的構(gòu)造函數(shù):一次是在創(chuàng)建子類型原型的時候,另一次...
    趙者也閱讀 375評論 0 0
  • 組合式繼承: 組合繼承的缺點:會調(diào)用兩次父類型構(gòu)造函數(shù),在子類型的原型上創(chuàng)造了不必要的、多余的屬性 寄生組合式繼承...
    櫻木夜訪流川楓閱讀 355評論 0 0
  • JS 繼承(三)寄生組合式繼承 JS 繼承(二)中說了組合繼承的模式,這種模式看起來似乎不錯的樣子,那么它有什么缺...
    IamaStupid閱讀 763評論 0 0
  • JS的繼承方式有很多種,最理想的繼承方式是寄生組合式繼承。組合繼承(構(gòu)造函數(shù)和原型的組合)會調(diào)用兩次父類構(gòu)造函數(shù)的...
    開始懂了_317閱讀 7,621評論 0 4
  • 組合式繼承的不足 組合繼承是JavaScript最常用的繼承模式,但也有它的不足: 無論什么情況下,都會調(diào)用兩次超...
    potato865閱讀 965評論 0 2

友情鏈接更多精彩內(nèi)容