• JavaScript-------寄生组合式继承


    组合继承在前面有说过,也是JavaScript中最常用的一个继承模式;不过,它也有自己的不足。组合继承最大的问题就是无论什么情况,都会调用两次构造函数:

    那我们来回顾下组合式继承基本模式:

     1         function SuperType(name){
     2             this.name = name;
     3             this.colors = ["red","blue","green"];
     4         }
     5         
     6         SuperType.prototype.sayName = function(){
     7             alert(this.name);
     8         }
     9         
    10         function SubType(name,age){
    11             //继承
    12             SuperType.call(this,name); 第二处
    13             this.age = age;
    14         }
    15         
    16         //继承方法
    17         
    18         SubType.prototype = new SuperType(); 第一处
    19         SubType.prototype.constructor = SubType;
    20         SubType.prototype.sayAge = function(){
    21             alert(this.age);
    22         }
    23         
    24         var instance1 = new SubType("Nicholas",20);
    25         instance1.colors.push("black");
    26         alert(instance1.colors);    

    上面红色标识的是调用构造函数的地方,在第一次调用SuperType 函数时,SubType.prototype会得到两个属性: name和colors;它们都是SuperType实例的属性,只不过现在位于SubType原型中。

    当调用SubType 构造函数时,会再调用一次SuperType函数,此时实例对象中会得到两个属性:name和colors; 此时相当于在同一个对象和原型中定义了两边相同的属性,不过由于实例中的同名属性会覆盖原型中的属性。

    看看下面草图可以能够理解些:

      如上图说明:存在两组属性一个原型上,一组是在实例中,这就是两次调用构造函数的结果,不过现在可以使用 寄生组合继承方式来解决;

    所谓寄生组合继承:即通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。

    背后的基本思路是:不必为了指定子类型的原型而调用超类型的构造函数,我们需要的无非就是超类型原型的一个副本而已。本质上,就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型。

      基本模式如下:

    1  function inheritPrototype(subType,superType){
    2        var prototype = Object.create(superType.prototype);
    3        prototype.constructor = subType;
    4        subType.prototype = prototype;
    5  }

      上面代码是寄生模式最简单组合方式,inheritPrototype() 接收两个参数,一个子类构造函数,父类构造函数,其中第一行代码是创建了一个父类原型对象的副本;第二行代码是修改副本对象的属性值,这里为什么修改想必大家都知道吧! 第三行 把生成好的副本对象赋值给子类的原型。这样就可以用这种方式去替换 前面代码中给原型赋值的语句  SubType.prototype = new SuperType()

    看看具体实例:

     1           function SuperType(name){
     2             this.name = name;
     3               this.colors = ["red","blue","green"];
     4           }
     5           
     6          SuperType.prototype.sayName = function(){
     7              alert(this.name);
     8          }
     9          
    10          function SubType(name,age){
    11              //继承
    12              SuperType.call(this,name); 第二处
    13              this.age = age;
    14          }
    15          
    16          //继承方法
    17         
    18         //SubType.prototype = new SuperType(); 第一处
    19         inheritPrototype(SubType,SuperType);
    20         SubType.prototype.constructor = SubType;
    21         SubType.prototype.sayAge = function(){
    22              alert(this.age);
    23         }    

    这个例子同样完成上一个实例的工作,但是更加高效率的体现在它只调用了一次SuperType()构造函数,并且因此避免了在SuperType.prototype 上面创建了不必要的、多余的属性。与此同时,原型链还能保持不变;因此,还能够使用instanceof 和 isPrototypeOf()。寄生组合式继承是引用类型最理想的继承范式。

  • 相关阅读:
    codeforces #601 div2 ABC~E1
    codeforces #600 div2 ABCD
    图形学 三次Hermite曲线绘制实现代码 javascript:es6+h5:canvas
    最小生成树(Prim / Kruskal)
    拓扑排序【Kahn算法(bfs)和dfs求拓扑序列及判环】
    Cow Traffic(正反向建图+DAG拓扑排序)
    JAVA大数
    【C/C++】关于strstr函数和c_str()函数
    【C/C++】关于函数调用传递实参
    2019上海icpc网络赛B. Light bulbs(思维+差分)
  • 原文地址:https://www.cnblogs.com/czhyuwj/p/5616707.html
Copyright © 2020-2023  润新知