JavaScript中的继承

一、 构造继承(经典继承)

  • 基本思想:用call() 或apply() 将父类的构造函数引入子类函数

  • demo

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    //父类
    function Person(name){
    this.name=name;
    this.sum=function(){
    alert(this.name)
    }
    }
    Person.prototype.age=10;

    //利用构造函数继承
    function Con(){
    Person.call(this,'jer')
    this.age=12;
    }
    var con1=new Con();
    console.log(con1.name);//'jer'
    console.log(con1.age);//12
    console.log(con1 instanceof Person);//false
  • 特点

    1. 只继承了父类构造函数的属性,没有继承分类原型的属性
    2. 每个新实例都有父类构造函数的副本
    3. 可以在 Child 中向 Parent 传参

二、原型链继承

  • 基本思想:让新实例的原型等于父类的实例,即 子构造函数.prototype = new 父构造函数()

  • demo

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    //父类
    function Person(name){
    this.name=name;
    this.sum=function(){
    alert(this.name)
    }
    }
    Person.prototype.age=10

    //原型链继承
    function Per(){
    this.name='ker';
    }
    Per.prototype=new Person();
    var per1=new Per();
    console.log(per1.age) //10
    console.log(per1 instanceof Person) //true
  • 特点

    1. 可继承父类构造函数的属性,父类原型的属性
    2. 所有新实例都会共享父类实例的属性。(原型上的属性是共享的,一个实例修改了原型属性,另一个实例的原型属性也会被修改!)

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

  • 基本思想:上述两种结合

  • demo

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function Person(name){
    this.name=name;
    this.sum=function(){
    alert(this.name)
    }
    }
    Person.prototype.age=10

    function SubType(name){
    Person.call(this,name)
    }
    SubType.prototype=new Person();
    var sub=new SubType('gar');
    console.log(sub.name) //'gar'
    console.log(sub.age)// 10

四、原型式继承

  • 基本思想:利用构造函数的原型对象实现继承,用一个函数包装一个对象,然后返回这个函数的调用

  • demo

    1
    2
    3
    4
    5
    6
    7
    8
    function content(obj){
    function F(){}
    F.prototype=obj
    return new F()
    }
    var sup=new Person()
    var sup1=content(sup)
    console.log(sup1.age) //10

五、寄生式继承

  • 基本思想:与原型式继承类似

  • demo

    function content(obj){
        function F(){}
        F.prototype=obj
        return new F()
    }
    var sup=new Person()
    
    function subObject(obj){
        var sub=content(obj)
        sub.name='gar';
        return sub;
    }
    
    var sup2=subobject(sup);
    console.log(typeof subobject);
    console.log(typeof sup2)
    console.log(sup2.name)
    
    

六、寄生组合式继承

  • 基本思想

  • demo

    function content(obj){
        function F(){}
        F.prototype=obj
        return new F()
    }
    var con=content(Person.prototype)
    
    //组合
    function Sub(){
        Person.call(this)
    }
    
    Sub.prototype=con;
    con.constructor=sub;
    var sub1=new Sub()
    
    console.log(sub1.age)//10
    
    
  • 特点

引用《JavaScript高级程序设计》中对寄生组合式继承的夸赞就是:这种方式的高效率体现它只调用了一次Parent构造函数,并且因此避免了在 Parent.prototype 上面创建不必要的、多余的属性。与此同时,原型链还能保持不变;因此,还能够正常使用 instanceof 和 isPrototypeOf。开发人员普遍认为寄生组合式继承是引用类型最理想的继承范式。