寄生组合式继承

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

组合式继承

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

  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中常见的继承方式(图解)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,692评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,482评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,995评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,223评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,245评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,208评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,091评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,929评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,346评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,570评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,739评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,437评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,037评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,677评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,833评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,760评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,647评论 2 354

推荐阅读更多精彩内容

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