JavaScript 继承 - - 寄生式组合继承(经典继承)

本文探讨了组合继承的伪经典问题,重点介绍了寄生式组合继承的解决方案,对比了其与ES6 Class的优劣,并列举了关键技术和应用场景。通过实例展示了如何避免原型污染,确保父级原型的独立性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、回顾 组合继承 (伪经典继承)

  • 结合了构造函数继承+对象原型继承

  • 不足的地方是:每个实例对象 都执行了两次Super函数,一次是prototype赋值,一次是Super.call

  • 并且 我们预期是想继承 父级的原型属性,而Suber.prototype = new Super(); 还另外承了this 对象,

   // 组合继承
    function Super() {
      this.pbrand = 'super';
      // 添加引用值
      this.a = [1, 2, 3, 4, 5];
    }
    function Suber() {
      this.bbrand = 'suber';
      //构造函数继承
      Super.call(this);           
    }
    Suber.prototype = new Super();  //对象原型继承
    let suber1 = new Suber();
    console.log(suber1);


 我曾想那把Suber.prototype = new Super(); , 改成Suber.prototype=Super.prototype;,那不是很奈斯?构造函数继承this,Suber.prototype = Super.prototype;继承prototype。后来经实践发现:

  function Super() {
      this.pbrand = 'super';
      // 添加引用值
      this.a = [1, 2, 3, 4, 5];
    }
    Super.prototype.b = ['a','b'];
    function Suber() {
      this.bbrand = 'suber';
      //构造函数继承
      Super.call(this);           
    }
    Suber.prototype = Super.prototype;
    Suber.prototype.str = 'suber';
    let suber1 = new Suber();
    console.log(suber1);

结果发现,Suber 与 Super的实例中原型值一样。因为 prototype 也是引用值,经过 Suber.prototype = Super.prototype,两者指向同一块内容。
在这里插入图片描述
那有没有完美解决伪经典继承缺陷的方法呢?有,那就是接下来的寄生式组合继承

二、寄生式组合继承

听名字猜它结合了哪些继承方式:寄生式,组合(构造)。

    // 经典继承 寄生式组合继承
    // 寄生式的核心:工厂函数
    function inheritPrototype(sub,sup){
      // Object.create是ES5才有的,为了兼容可以自己写一个函数
      // 只继承了prototype
      let prototype = Object.create(sup.prototype);
      sub.prototype = prototype;
      // 增强对象:标明构造函数
      prototype.constructor = sub;
    }
    // 父级
    function Super(){
      this.brand = 'super';
      this.a = ['a','b'];
    }
    Super.prototype.say = function(){
      console.log('i`m ',this.brand);
    }
    // 子级
    function Suber (){
      this.brand = 'suber';
      this.a = [1,2,3,4];
      Super.call(this);
    }
    //调用工厂函数实现继承
    inheritPrototype(Suber,Super);

    let suber1 = new Suber();
    let super1 = new Super();

    // 修改一下子级的原型
    Suber.prototype.str = 'suber';
    
    console.log(suber1);
    console.log(super1);

 结果可以看出:

  • 子级的原型更改,不会影响到父级的原型,
  • 父级的原型,子级也能继承
  • 父级的this 对象,子级也能继承
  • 所以这是经典继承

在这里插入图片描述

要说还有没有别的继承:es6 新引入的class了解一下…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值