javascript之原型继承

今天在图书馆搞了一个下午才算优点门道的原型继承问题。书上说有多种,我现在摘下几个比较连贯的方法,这样学习起来比较深刻。另外几种都是可以在这几种方法中看到影子,比较好理解,就没有摘录下来。

1.1 原型链

  原型链是指一个构造函数的原型是另一个构造函数的实例,从而实现继承。

  (1)原型中包含constructor指向构造函数;

  (2)实例中包含[[prototype]]指向构造函数的原型;

  (3)当前一个构造函数实例化后,即可继承后一个构造函数的属性与方法。

 

  由于后一个构造函数的属性变成了前一个构造函数的原型,因此,在实际应用中会导致和原型创建对象同样的问题——改变一个实例的引用数据,其他所有实例都将发生改变。

  另外,后一个构造函数无法传入引用类型的数据,因为,该构造函数中的属性即为前一个构造函数的原型,这同样是导致同样的问题。

 

1.2 借用构造函数

    function SuperType(){
       this.colors =['red', 'blue', 'green'];
    };

    function SubType(){
       //继承 SuperType
       SuperType.call(this); //此处同样可以使用apply方法
    };
    var instance1 = new SubType();
    instance1.colors.push('black');
    alert(instance1.colors);
    
    var instance2 = new SubType();
    alert(instance2.colors);
View Code

 

  当然,这样同样可以在call中实现向SuperType()中传递参数。

  但是,这还是存在问题:所有的参数都在SubType函数中进行定义,那这种重用性就无从谈起了。

 

1.3 组合继承

  结合原型链和借用构造函数的技术,从而发挥两者的长处得到。即将私有的属性放在构造函数中,将共享的属性放在原型中。

  

  组合继承是当前最常用的方式。

 

  组合式继承中需要两次调用超类,因此有人提出了寄生式继承。

 

1.4 寄生式继承

  先定义一个实例,然后将实例传递给构造函数的原型,同时将其中的constructor重新指向构造函数,然后在实例化时,调用超类即可。代码如下:

  

      //寄生式继承
      function SuperType(name){
           this.name = name;
           this.colors = ['red', 'blue', 'green'];
      };
      SuperType.prototype.getSuperVal = function(){
           alert(this.name)
      };

      function SubType(name, age){
           SuperType.call(this, name);
           this.age = age;
      };
      function inheritFromSuper(SubType, SuperType){
           SubType.prototype = Object.create(new SuperType());
           SubType.prototype.constructor = SubType;
      };
      inheritFromSuper(SubType, SuperType);
      SubType.prototype.getSubVal = function(){
           alert(this.age);
      };
      var instance1 = new SubType('A', 29);
      var instance2 = new SubType('B', 20);
      instance1.colors.push('black');
      alert(instance1.colors);
      alert(instance2.colors);                                

 

 

posted @ 2017-03-05 22:15  前端狗狗狗狗狗  阅读(126)  评论(0编辑  收藏  举报