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()就是采用这种寄生组合式继承

  • 相关阅读:
    【转】将项目打成war包并用tomcat部署的方法,步骤及注意点
    JETTY+NGINX
    【转】收集 jetty、tomcat、jboss、weblogic 的比较
    SQL左右连接中的on and和on where的区别
    定义一个servlet用于处理所有外部接口类 架构思路
    spring上下文快速获取方法
    jasper打印实例2 ----通过文件字节流获得PDF格式图片
    Jasper打印示例
    Jasperreport5.6.9-----1
    Linux装B命令
  • 原文地址:https://www.cnblogs.com/YeChing/p/6351240.html
Copyright © 2011-2022 走看看