zoukankan      html  css  js  c++  java
  • 理解JavaScript继承(二)

    理解JavaScript继承(二)

    5.寄生式继承

    function object(o) {
        function F() {}    
        F.prototype = o;  
        return new F();
    }
    
    function createAnother(original){
      var clone = object(original);//通过调用函数创建一个新对象
      clone.sayHi=function(){//以某种方式增强这个对象
        alert("hi");
      };
      return clone;//返回这个对象
    }
    
    var person={
      name:"Nicholas",
      friends:["Shelby","Court,"Van"]
    };
    
    var anotherPerson=createAnother(person);
    anotherPerson.sayHi();//"hi"
    

    这个实例基于person返回了一个新对象anotherPerson。新对象不仅具有person的所有属性和方法,而且还有自己的sayHi()方法。

    缺点:和构造函数一样,不能做到函数复用而降低效率。

    6.寄生组合式继承

    前面介绍说组合继承是JavaScript最常用的继承模式;实际上,它也存在一些问题,组合继承的最大问题是无论什么情况下,都会调用两次超类型构造函数:一次是在创建子类型原型的时候,另一次是在子类型构造函数内部。

    组合式继承实例

    function SuperType(name){
        this.name = name;
        this.colors = ["red", "blue", "green"];
    }
            
    SuperType.prototype.sayName = function(){
        alert(this.name);
    };
    
    function SubType(name, age){  
        SuperType.call(this, name);//第二次调用SuperType()
                
        this.age = age;
    }
    
    SubType.prototype = new SuperType();//第一次调用SuperType()
            
    SubType.prototype.sayAge = function(){
        alert(this.age);
    };
    

    在第一次调用SuperType()构造函数时,SubType.prototype会得到两个属性:name和colors;他们都是SuperType的实例属性,只不过现在位于SubType的原型中。当调用SubType构造函数时,又会调用一次SuperType构造函数,这一次又在新对象上创建了实例属性name和colors,于是,这两个属性就屏蔽了原型中的两个同名属性。

    上面一共有两组name和colors属性:一组在实例上,一组在SubType原型中。这就是调用两次SuperType的结果。

    为了解决这种情况,于是就出现了下面的——寄生组合式继承方法。

    所谓寄生组合式继承,即通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。其背后的基本思路是:不必为了指定子类型的原型而调用超类型的构造函数,我们所需要的无非就是超类型原型的一个副本而已。(之所以是超类型的副本,而不是直接是超类型,如果直接是超类型的话。当子类型为原型添加方法时,也会影响到超类型的)

    寄生组合式继承

    function object(o){
        function F(){}
        F.prototype = o;
        return new F();
    }
        
    function inheritPrototype(subType, superType){
        var prototype = object(superType.prototype);   //创建对象
        prototype.constructor = subType;               //增强对象
        subType.prototype = prototype;                 //指定对象
    }
                                    
    function SuperType(name){
        this.name = name;
        this.colors = ["red", "blue", "green"];
    }
            
    SuperType.prototype.sayName = function(){
        alert(this.name);
    };
    
    function SubType(name, age){  
        SuperType.call(this, name);
                
        this.age = age;
    }
    
    inheritPrototype(SubType, SuperType);
            
    SubType.prototype.sayAge = function(){
        alert(this.age);
    };
            
    var instance1 = new SubType("Nicholas", 29);
    instance1.colors.push("black");
    alert(instance1.colors);  //"red,blue,green,black"
    instance1.sayName();      //"Nicholas";
    instance1.sayAge();       //29
            
           
    var instance2 = new SubType("Greg", 27);
    alert(instance2.colors);  //"red,blue,green"
    instance2.sayName();      //"Greg";
    instance2.sayAge();       //27
    

    上面实例只在SuperType.call(this, name);这调用了一次构造函数,并且因此避免了在prototype上面创建不必要的,多余的属性。

    注:YUI的extend()就是采用这种寄生组合式继承

  • 相关阅读:
    POJ 1251 Jungle Roads
    1111 Online Map (30 分)
    1122 Hamiltonian Cycle (25 分)
    POJ 2560 Freckles
    1087 All Roads Lead to Rome (30 分)
    1072 Gas Station (30 分)
    1018 Public Bike Management (30 分)
    1030 Travel Plan (30 分)
    22. bootstrap组件#巨幕和旋转图标
    3. Spring配置文件
  • 原文地址:https://www.cnblogs.com/YeChing/p/6351240.html
Copyright © 2011-2022 走看看