js中的几种继承方法

JS作为面向对象的弱类型语言,继承也是其非常强大的特性之一。

继承:子承父业;一个原本没有某些方法或属性的对象,统一写方法,拿到了另外一个对象的属性和方法

下面是js中的几种继承方式

1.改变this指向继承(构造函数继承):继承构造函数中的属性和方法

 function Parent(n){
        this.name = n;
        this.skill = function(){
            console.log(this.name + "是篮球运动员");     //樱木花道是篮球运动员
                                                       //泽北荣治是篮球运动员
        }
    }
    Parent.prototype.init = function(){
        console.log(123)                               //123
    }

    // function P2(){
    //     this.a = 10;
    // }
    // function P3(){
    //     this.b = 20;
    // }
    // function P4(){
    //     this.c = 30;
    // }
    
    function Child(n){
        // Parent.bind(this,n)();
        // P2.bind(this)()
        // P3.bind(this)()
        // P4.bind(this)()

        // Parent.call(this,n);

        Parent.apply(this,arguments);
    }

    var p = new Parent("樱木花道");
    console.log(p)
    p.skill();       //
    p.init()

    var c = new Child("泽北荣治");
    console.log(c)
    c.skill();           //   
    // console.log(c.a)
    // console.log(c.b)
    // console.log(c.c)
    // c.init()

优点:简单方便易操作,可以多继承

缺点:只能继承构造函数,不能继承原型

2.原型对象继承:继承原型

function Parent(n){
        this.name = n;
    }
    Parent.prototype.skill = function(){
        console.log(this.name + "是鉴定师");       //大老王是鉴定师
                                                 //小老王是鉴定师
    }

    function Child(n){
        this.name = n;
    }

    // 注意:对象的深浅拷贝
    for(var i in Parent.prototype){
        Child.prototype[i] = Parent.prototype[i];
    }


    var p = new Parent("大老王");
    console.log(p)                            //Parent {name: "大老王"}
    p.skill();

    var c = new Child("小老王");
    console.log(c)                            //Child {name: "小老王"}
    c.skill();

优点:简单,方便,可以继承原型身上的方式和属性
缺单:只能继承原型,不方便传参

3.原型链继承:通过给Child设置原型为Parent的实例的方式,给Child添加了一层原型链的方式

 function Parent(n){
        this.name = n;
    }
    Parent.prototype.skill = function(){
        console.log(this.name + "是鉴定师");           //大老王是鉴定师
    }

    function Child(){}
    Child.prototype = new Parent("小老王");

    Child.prototype.skill = function(){
        console.log(this.name+"是运动员")             //小老王是运动员
    } 

    var p = new Parent("大老王");
    console.log(p)                                 //Parent {name: "大老王"}
    p.skill();
    // p是实例(对象),有__proto__属性,指向Parent.prototype

    var c = new Child();
    console.log(c);                              //Child {}
    c.skill();
    // c是实例(对象),有__proto__属性,指向Child.prototype,是Parent的实例(对象),有__proto__属性,指向Parent.prototype

优点:既能继承原型,又能继承构造函数
缺点:复杂,不方便传参

4.混合继承:构造函数继承+原型对象继承

 function Parent(n){
        this.name = n;
    }
    Parent.prototype.skill = function(){
        console.log(this.name + "是鉴定师");              //大老王是鉴定师
    }

    function P2(){
        this.a = 10;
    }
    P2.prototype.init = function(){
        console.log("hello")                        //hello
    }

    function Child(n){
        Parent.call(this,n)
        P2.call(this)
    }
    for(var i in Parent.prototype){
        Child.prototype[i] = Parent.prototype[i]
    }
    for(var i in P2.prototype){
        Child.prototype[i] = P2.prototype[i]
    }

    Child.prototype.skill = function(){
        console.log(123)                            //123
    }
   

    var p = new Parent("大老王");
    console.log(p)                           //Parent {name: "大老王"}
    p.skill();

    var c = new Child("小老王");
    console.log(c)                          //Child {name: "小老王", a: 10}
    c.skill();
    c.init();

优点:既能继承构造函数又能继承原型,方便传参,多继承

缺点:复杂

常用的继承方式之一

5.ES6的class继承

class Parent{
        constructor(n) {
            this.name = n
        }
        skill(){
            console.log(this.name + "是鉴定师")         //大老王是鉴定师
                                                      //小老王是鉴定师
        }
    }

    class Child extends Parent{
        constructor(n){
            super(n)
        }
    }

    var p = new Parent("大老王");
    console.log(p)                              //Parent {name: "大老王"}
    p.skill();

    var c = new Child("小老王");                //Child {name: "小老王"}
    console.log(c)
    c.skill();

优点:简单方便易操作,语法层面的继承,属性和方法都能继承,参数很好处理

缺点:兼容性

忽略兼容,常用的继承方式之一

原文地址:https://www.cnblogs.com/mhcll/p/11563142.html