1.原型继承

 
    function SuperType(){
        this.property = "SuperType";
    }
    SuperType.prototype.getValue = function(){
        return this.property;
    }

    function  SubType(){
        this.subproperty ="SubType";
    }
    //继承SuperType
    SubType.prototype = new SuperType();

    SubType.prototype.getSubValue = function(){
        return this.subproperty;
    };

    var sub = new SubType();
    alert(sub.getValue());   //SuperType,输出继承而来的函数
    alert(sub.getSubValue());  //SubType,输出本身定义的函数

继承是通过创建SubType.prototype = new SuperType(); SuperType实例,赋给SubType.prototype。实现的本质是重写原型对象

var sub = new SubType();创建SubType实例,新原型就是这个实例,这个新原型中不但拥有SuperType所有属性和方法

注意:通过原型链实现继承时不能使用字面量创建原型方法,因为这样做会重写原型链
原型链的问题
1.引用类型值的原型属性被所有实例共享,一个实例的修改也会改变其他实例的值
2.在创建子类型的实例时,不能向超类型的构造函数中传递参数。
2.借用构造函数(伪造对象或是经典继承)
基本思想很简单,在子类型构造函数的内部调用超类型构造函数。
 
       function  SuperType2(){
        this.colors = ["red", "blue", "black"];
    }

    function SubType2(){
        //继承SuperType2
        SuperType2.call(this);
    }

    var instance1 = new  SubType2();
    instance1.colors.push("yellow"); 
    alert(instance1.colors);//输出red,blue,black,yellow


    var instance2 = new  SubType2();
    alert(instance2.colors);//输出red,blue,black

2.传递参数

借用构造函数一大优势就是子类型向超类型传递数据

    //借用构造函数
    function  SuperType2(name){
        this.colors = ["red", "blue", "black"];
        this.name =name;
    }

    function SubType2(){
        //继承SuperType2
        SuperType2.call(this,"Dnery");
        this.age = 29;
    }

    var instance1 = new  SubType2();
    instance1.colors.push("yellow");
    alert(instance1.colors);


    var instance2 = new  SubType2();
    // alert(instance2.colors);
    alert(instance2.name);
    alert(instance2.age);</pre> 

借用构造函数问题
方法都在构造函数中定义,没有函数复用,而且在超类型中定义的方法,子类型中是不可见的,结果所有类型只能用构造函数模式。
所以很少单独使用

3.组合继承(最常用的继承方式)

也叫伪经典继承,指的是将原型链和借用构造函数的技术组合到一块。
背后思路是使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。
这样,即通过在原型上定义方法实现了函数复用,又能够保证每个实例都有它自己的属性。


 
            //组合继承
    function SuperType3(name){
        this.name = name;
        this.colors = ["red","green"];
    }
    SuperType3.prototype.sayName = function(){
        alert(this.name);
    }

    function SubType3(name, age){
        //继承属性
        SuperType3.call(this,name); //第二次调用,创建了实例属性,所以覆盖掉了第一次调用原型上面的属性
        this.age =age;
    }

SubType3.prototype = new SuperType3();  //第一次调用
SubType3.prototype.constructor=  SubType3;
SubType3.prototype.sayAge = function(){
    alert(this.age);
}

var ins1 = new  SubType3("denry","23");
ins1.colors.push('red');
    alert(ins1.colors);
ins1.sayName();
ins1.sayAge();    

var ins2 = new  SubType3("denry","23");
alert(ins2.colors);
ins2.sayName();
ins2.sayAge();

4.原型式继承

必须有一个对象作为另一个对象的基础,把基础对象传递给对象,然后再根据具体需求加以修改即可。新对象相当于创建基础对象的副本

ECMASCRIPT5 新增的Object.create()方法规范了原型式继承

 var person = {
     name:'denry',
     firends:['A','B','C']
 };
 var aPerson = Object.create(person);
 aPerson.name = "BBB";
 aPerson.firends.push("D");    

  var bPerson = Object.create(person);
 bPerson.name = "CCC";
 bPerson.firends.push("E");
 alert(aPerson.firends);   //A,B,C,D,E

 

在保持一个对象与另一个对象相似的情况下,原型式继承是完全可以胜任的。

注意:包含引用类型的值始终会共享相应的值,就像使用原型模式一样

5.寄生式继承

即创建一个用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后在像真的是它做了所有工作一样返回对象



 //5.寄生式继承
    function  createAnother(original){
        var clone = Object(original);
        clone.sayHi = function(){
            alert("Hi");
        };

        return clone;
    }

    var person4 = {
        name:'Denry',
        friends:["A","B","C"]
    }
    var aPerson4 = createAnother(person4);
    aPerson4.sayHi();  //Hi

上面的例子基于person4对象返回了一个新对象
在主要考虑对象而不是自定义类型和构造函数的情况下,寄生式继承是一种有用的模式。

6.寄生组合式继承

组合继承会调用两次构造函数,
背后思路:不必为了指定子类型的原型而调用超类型的构造函数。本质上,就是使用寄生式继承来继承超类型的原型。

     function SuperType6(name){
        this.name = name;
        this.colors = ["red","green"];
    }
    SuperType6.prototype.sayName = function(){
        alert(this.name);
    }


    function SubType6(name, age){
        // 借用构造函数来实现对实例属性的继承
        SuperType3.call(this,name);
        this.age =age;
    }

    //原型链实现对原型属性和方法的继承
    function inhert(SubType6,SuperType6){
        var pro = Object(SuperType6.prototype); //创建对象
        pro.constructor = SubType6;                //增强对象,弥补因重写原型失去的constructor属性
        SubType6.prototype = pro;                //指定对象
    }


    inhert(SubType6, SuperType6);

    var test = new SubType6("哈哈",0);
    test.sayName();

只调用了一次构造函数,认为寄生组合式继承是引用类型最理想的继承范式。

最后修改:2019 年 01 月 30 日
如果觉得我的文章对你有用,请随意赞赏