zoukankan      html  css  js  c++  java
  • 整理js继承

    实现继承的方法:

    一,原型链:利用原型让一个引用类型继承另一个引用类型的属性和方法

    function SuperType(){
        this.property=true;
    }
    
    SuperType.prototype.getSuperValue=function(){
        return this.property;
    };
    function SubType(){
    
        this.subproperty=false;
    }
    //继承了SuperType
    SubType.prototype=new SuperType();
    SubType.prototype.getSubValue=function(){
          return this.subproperty;
    
    }
     var instance=new SubType();
     alert(instance.getSuperValue());  //true

    注意问题:

    a:所有引用类型默认都继承了Object,也是通过原型链实现的,所有函数的默认原型都是Object的实例。

    alert(instance instanceof Object);  //true

    b:确定原型和实例之间的关系,可以用instanceof操作符和isPrototypeOf()方法。

    实例与原型链中出现过的构造函数都会返回true。

    alert(instance instanceof SubType);  //true 

    原型链中出现过的原型,都可以说是原型链派生的实例的原型,返回true。

    alert(SubType.prototype.isPrototypeOf(instance));  //true

    c:给原型添加方法的代码一定要放在替换原型的语句之后。

    d:通过原型链实现继承时不能使用对象字面量创建原型的方法,这样会重写原型链,之前的原型链被切断,SubType和SuperType之间没有关系了。

    e:原型链的问题:每个实例都会共享属性,子类型不能向超类型中传参

    优点:实例的方法可以共享

    缺点:所有实例的属性共享

    二,借用构造函数:在子类的构造函数内部调用超类型构造函数

    function SuperType(){
        this.colors=["red","blue","green"];//该数组就是引用类型值
    }
    function SubType(){
       //继承了SuperType
       SuperType.call(this);//SuperType.call(this)的意思就是使用SuperType 对象代替this对象,那么Subtype中不就有SuperType的所有属性和方法了,instance1对象就能够直接调用SuperType的方法以及属性了
    }
    var instance1=new SubType();
    instance1.colors.push("black");
    alert(instance1.colors);  //red,blue,green,black
    
    var instance2=new SubType();
    alert(instance2.colors);//red,blue,green 

    a:可以传递参数

    b:借用构造函数问题:方法都在构造函数中定义,因此所有函数无法复用

    优点:解决了原型链实现继承属性共享的问题,可以传递参数

    缺点:函数无法复用,每个实例的方法都不相同

    三,组合继承:将原型链和借用构造函数的技术组合到一块,扬长补短,思想:使用原型链对原型属性和方法的继承,使用借用构造函数实现对实例属性的继承。

    function SuperType(name){
                this.colors=["red","green","blue"];
                this.name=name;
            }
            //用原生链的方式将方法写在外面,让每个实例使用相同的方法
            SuperType.prototype.sayName=function(){
                alert(this.name);
            };
            function SubType(name,age){
                //第二次调用SuperType()
                SuperType.call(this,name);  //让每个实例分别拥有自己的属性
                this.age=age;
            }
            //继承方法
            SubType.prototype=new SuperType();   //第一次调用SuperType()
            //弥补因重写原型而失去的默认的constructor属性
            SubType.prototype.constructor=SubType; 
            SubType.prototype.sayAge=function(){
                alert(this.age);
            };
    
            var instance1=new SubType("jane",29);
            instance1.colors.push("black");
            alert(instance1.colors); //red,green,blue,black
            instance1.sayName();  //jane
            instance1.sayAge();  //29
    
            var instance2=new SubType("tom",30);
            alert(instance2.colors);//red,green,blue
            instance2.sayName();  //tom
            instance2.sayAge();  //30
    
            alert(instance1.sayName==instance2.sayName);  //true
            alert(SubType.prototype.constructor==SubType);//true

    优点:最常用的继承模式,解决了借用构造函数,函数不能复用的问题,以及原型链属性共享,以及不能传参的问题

    缺点:如代码中所说,调用了两次超类型构造函数,如果删除instance2的colors属性,依然会返回red,green,blue,这样就无法删除colors属性

    delete instance2.colors;
    alert(instance2.colors);//red,green,blue

    四,原型式继承:基于已有的对象创建新对象

    Object.create()方法实现原型式继承:

    //传入一个参数的情况下,对象名
      var person={
           name:"jane",
           friends:["tom","nike","van"]
       };
    
       var anotherPerson=Object.create(person);
       anotherPerson.name="greg";
       anotherPerson.friends.push("rob");
    
       var yetAnotherPerson=Object.create(person);
       yetAnotherPerson.name="linda";
       yetAnotherPerson.friends.push("barbie");
    
       alert(person.friends); //tom,nike,van,rob,barbie*
    //Object.create()方法传入两个参数,第一个参数,对象名,第二个参数:属性都是通过自己的描述符定义的。
    var person={
        name:"jane",
        friends:["tom","nike","van"]
    };
    var anotherPerson=Object.create(person,
        {
        //以这种方式指定的任何属性都会覆盖原型对象上的同名属性。 name:{ value:
    "greg" } } ); alert(anotherPerson.name); //greg

    优点:不用再创建自定义的类型了

    缺点:引用类型值的属性都会共享相应的值

    五,寄生式继承:封装继承过程的函数

    //createAnother函数接收了一个参数,也就是将要作为新对象基础的对象。
    function createAnother(original){
        //把original对象传递给Object函数,将返回的结果赋给clone
        var clone=Object(original);
        //再为clone对象添加一个方法
        clone.sayHi=function(){  
          alert("hi");
        };
        return clone;//返回这个对象
    }
    
    var person={
        name:"jane",
        friends:["tom","nike","van"]
    };
    
    var anotherPerson=createAnother(person);
    anotherPerson.sayHi();//hi  anotherPerson具有Person不具有的方法sayHi()

    优点:为对象添加函数

    缺点:函数无法复用

    六,寄生组合式继承:使用寄生式继承超类型的原型,再将结果返回给子类型的原型。

    function inheritPrototype(SubType,SuperType){
                var prototype=Object(SuperType.prototype);//创建对象
                prototype.constructor=SubType;  //弥补因重写原型而失去的默认的constructor属性
                SubType.prototype=prototype;//指定对象
            }
    function SuperType(name){
                this.name=name;
                this.colors=["red","green","blue"];
            }
     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 instence=new SubType("jane",29);
     instence.sayName();
     instence.sayAge();

    优点:解决了组合继承的两次调用超类型构造函数问题

     

  • 相关阅读:
    第二阶段站立会议05
    第二阶段站立会议04
    第一阶段冲刺总结
    站立会议08
    站立会议07
    站立会议06
    站立会议05
    站立会议04
    第一次冲刺第3天
    站立会议2
  • 原文地址:https://www.cnblogs.com/wgj32/p/5722806.html
Copyright © 2011-2022 走看看