js几种继承

提示:主要是原型链继承、构造函数继承、原型链加构造函数继承、寄生组合式继承


一、原型链继承

子类想要继承父类的属性和方法,可以将其原型对象指向父类的实例,根据原型链就可以使用到父类的方法和属性

    // 父类
    function Parent() {
      this.name = ['父类']
      this.introduce = function () {
        console.log("my name is" + this.name)
      }
    }
    // 子类
    function Child() {
      this.childname = ['子类']
    }

    // 核心代码:
    Child.prototype = new Parent()
    var child1 = new Child()
    console.log(child1)

  输出的结果:

                

 child已经继承了父类的方法,但是缺点就是多个子类实例对父类引用类型的操作会被纂改,无法保持子类实例的个性。如:

    var child1 = new Child()
    child1.name[0] = 'child1唱歌'
    var child2 = new Child()
    child2.name[0] = 'child2跳舞'
    console.log(child1.name);
    console.log(child2.name);

输出结果:

         

 child1和child2继承的父类的name属性是一个数组,对其操作时更改会互相影响。


二、构造函数继承

在子类的构造函数中,执行父类的构造函数,并且为其绑定子类的this

    // 父类
    function Parent() {
      this.name = ['父类']
      this.introduce = function () {
        console.log("父类上的introduce方法")
      }
    }
    Parent.prototype.sayhi = function () {
      console.log('父类原型上的sayhi方法');
    }
    // 子类
    function Child() {
      this.childname = ['子类']
      Parent.call(this)
    }

    var child1 = new Child()
    child1.introduce()
    child1.sayhi()

上述代码的结果是:

         

 构造函数继承可以继承到父类上的属性和方法,但是继承不到父类原型上的属性和方法


三、原型链加构造函数继承

    // 父类
    function Parent() {
      this.name = ['父类']
      this.introduce = function () {
        console.log("父类上的introduce方法")
      }
    }
    Parent.prototype.sayhi = function () {
      console.log('父类原型上的sayhi方法');
    }
    // 子类
    function Child() {
      this.childname = ['子类']
      Parent.call(this) // 第二次调用Parent
    }

    Child.prototype = new Parent() // 第一次调用Parent

    var child1 = new Child()
    console.log(child1);

输出结果:

         

 第一次调用Parent(),在Child.prototype写入了父类的name和introduce属性和方法,第二次再调用Parent(), 给实例child1又写入了name和introduce属性和方法。实例child1上的name和introduce屏蔽了原型对象Parent.prototype的两个同名属性,所以组合模式的缺点就在使用子类创建实例对象的时候,其原型中会存在两份相同的属性和方法.


 四、原型式继承

利用一个空对象作为中介、将某个对象直接赋值给空对象构造函数的原型,其实就是使用Object.create()

    var Parent = {
      name: ['父类属性'],
      sayhi: function () {
        console.log(this.name);
      }
    }

    var child1 = Object.create(Parent)
    var child2 = Object.create(Parent)
    child1.name[0] = 'child1属性'
    child2.name[0] = 'child2属性'
    console.log(child1);

缺点:跟原型链继承一样,多个子类实例的引用类型属性指向相同,可能会纂改。 


五、寄生组合式继承

     // 父类
    function Parent() {
      this.name = ['父类']
      this.introduce = function () {
        console.log("父类上的introduce方法")
      }
    }
    Parent.prototype.sayhi = function () {
      console.log('父类原型上的sayhi方法');
    }
    // 子类
    function Child() {
      this.childname = ['子类']
      Parent.call(this) // 核心代码
    }
    Child.prototype = Object.create(Parent.prototype) // 核心代码

    const child1 = new Child()
    const child2 = new Child()
    child1.name[0] = 'child1'
    child2.name[0] = 'child2'
    console.log(child1);
    console.log(child1.name);
    console.log(child2.name);

 完美解决原型链加构造函数继承的缺点

mark一下,明天接着写

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值