zoukankan      html  css  js  c++  java
  • 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()。寄生组合式继承是引用类型最理想的继承范式。

  • 相关阅读:
    再谈TextField
    IOS-TextField知多少
    leftBarButtonItems
    LeftBarButtonItems,定制导航栏返回按钮
    Apple Mach-O Linker (id) Error "_OBJC_CLASS...错误解决办法 Apple Mach-O Linker (id) Error "_OBJC_CLASS...错误解决办法
    Unrecognized Selector Sent to Instance问题之诱敌深入关门打狗解决办法
    UNRECOGNIZED SELECTOR SENT TO INSTANCE 问题快速定位的方法
    Present ViewController,模态详解
    UILABEL AUTOLAYOUT自动换行 版本区别
    iOS自动布局解决警告Automatic Preferred Max Layout Width is not available on iOS versions prior to 8.0
  • 原文地址:https://www.cnblogs.com/czhyuwj/p/5616707.html
Copyright © 2011-2022 走看看