js继承的7种方式


一、原型链继承

<script>
    function Person(name) {
      this.name = name 
      this.sum = function() {
        // return new Date()
        return 33
      }
    }
    Person.prototype.age = 10

    //原型链继承
    /*
    重点:让新实例的原型等于父类的实例。
    特点:1、实例可继承的属性有:实例的构造函数的属性,父类构造函数属性,父类原型的属性。
            (新实例不会继承父类实例的属性!)
    缺点:1、新实例无法向父类构造函数传参。
       2、继承单一。
       3、所有新实例都会共享父类实例的属性。(原型上的属性是共享的,一个实例修改了原型属性,
             另一个实例的原型属性也会被修改!)
    */
    function Per() {
      this.name = 'pick'
      this.age = 1
    }
    Per.prototype = new Person()
    var per1 = new Per()
    console.log(per1.name);  //pick
    console.log(per1.age);   //1
    console.log(per1.sum());  // 33
    // instanceof 判断元素是否在另一个元素的原型链上
    console.log(per1 instanceof Person); //true
  </script>

二、构造函数继承

  <script>
    function Person(name) {
      this.name = name 
      this.sum = function() {
        // return new Date()
        return 33
      }
    }
    Person.prototype.age = 10
    
    //构造函数继承
    /*
    重点:用.call()和.apply()将父类构造函数引入子类函数(在子类函数中做了父类函数的自执行(复制))
    特点:1、只继承了父类构造函数的属性,没有继承父类原型的属性。
       2、解决了原型链继承缺点1、2、3。
       3、可以继承多个构造函数属性(call多个)。
       4、在子实例中可向父实例传参。
    缺点:1、只能继承父类构造函数的属性。
       2、无法实现构造函数的复用。(每次用每次都要重新调用)
       3、每个新实例都有父类构造函数的副本,臃肿。
    */
    function Cons() {
      Person.call(this,'jack')
      this.age = 12 // 屏蔽则以下undefined
    }
    const cons = new Cons()
    console.log(cons.name); // jack
    console.log(cons.age); // 12
    // instanceof 判断元素是否在另一个元素的原型链上
    console.log(cons instanceof Person); //false
  </script>

三、组合继承(组合原型链继承和借用构造函数继承)(常用)

  <script>
    function Person(name) {
      this.name = name 
      this.sum = function() {
        // return new Date()
        return 33
      }
    }
    Person.prototype.age = 10
    
    //组合继承(组合原型链继承和借用构造函数继承)(常用)
    /*
    重点:结合了两种模式的优点,传参和复用
    特点:1、可以继承父类原型上的属性,可以传参,可复用。
       2、每个新实例引入的构造函数属性是私有的。
    缺点:调用了两次父类构造函数(耗内存),子类的构造函数会代替原型上的那个父类构造函数。
    */
    function SubType(name) {
      Person.call(this,name)
    }
    SubType.prototype = new Person()
    var sub = new SubType('haha')
    console.log(sub.name); // haha
    console.log(sub.age); // 10
    // instanceof 判断元素是否在另一个元素的原型链上
    console.log(sub instanceof Person); //true
  </script>

四、寄生组合式继承(常用)

<script>
    function Person(name) {
      this.name = name 
      this.sum = function() {
        // return new Date()
        return 33
      }
    }
    Person.prototype.age = 10
    
    //寄生组合式继承(常用)
    /*
    寄生:在函数内返回对象然后调用
    组合:1、函数的原型等于另一个实例。2、在函数中用apply或者call引入另一个构造函数,可传参 
       重点:修复了组合继承的问题
    */
    function content(obj) {
      function F() {}
      F.prototype = obj
      return new F()
    }
    // content就是F实例的另一种用法
    var con = content(Person.prototype)
    //con实例(F实例)的原型继承父类函数的原型
    
    //组合
    function Sub() {
      Person.call(this,'haha')
    }
    Sub.prototype = con //继承con实例
    con.constructor = Sub //修复实例
    var sub1 = new Sub()

    console.log(sub1.name); // haha
    console.log(sub1.age); // 10
    // instanceof 判断元素是否在另一个元素的原型链上
    console.log(sub1 instanceof Person); //true
  </script>

五、class继承

class Parent5 {
  constructor() {
    this.name = ['super5']
  }
  reName() {
    this.name.push('new 5')
  }
}
class Child5 extends Parent5 {
  constructor() {
    super()
  }
}
var child51 = new Child5()
var child52 = new Child5()

六、原型式继承

。。。

七、寄生式继承

。。。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值