js 继承

    今天看的《JavaScript设计模式》-作者:张容铭。主要看了js继承。下面我将看的,以及代码贴出来,跟大家一起学习,分享。共同进步。

   先来个简单是

  单继承

   

//单继承

var extend=function(target,source){
    //遍历原对象的所有属性
    for(var i in source){
        //将原对象中的属性复制到目标对象中
        target[i]=source[i];
    }
    //返回目标对象
    return target;
    //这是浅拷贝
}

多继承

       

//多继承

var mix=function(){
    
    var i=1;//从第二个参数开始
    var arg;//缓存arguments参数
    var len=arguments.length;//参数长度
    var target=arguments[0];
    for(;i<len;i++){
        arg=arguments[i];
        //遍历原对象的所有属性
        for(var a in arg){
            //将原对象中的属性复制到目标对象中
            target[a]=arg[a];
        }
    }
    
    //返回目标对象
    return target;
    //这是多对象浅拷贝(data,ds,de);会把ds,de的各个属性方法拷贝到data,不好之处,有可能ds的属性会被de的属性覆盖
}

类继承
   是通过子类的原型prototype对父类实例化来实现的
   缺点:父类中的共有属性如果是引用类型就会在子类的所有实例中共拥有,一旦被某一个实例改变,则父类中的共有属性改变。

        //声明
        function SuperClass(){
            //共有属性--如果是引用类型(数组,对象)就会有问题
            this.superValue=true;
        }
        //为父类添加共有方法
        SuperClass.prototype.getSuperValue=function(){
            return this.superValue;
        }
        //声明子类
        function SubClass(){
            this.subValue=false;
        }
        //继承父类
        SubClass.prototype=new SuperClass;
        //为子类添加共有方法
        SubClass.prototype.getSubValue=function(){
            return this.subValue;
        }
        
        var instan=new SubClass;
        console.log(instan.getSuperValue());
        console.log(instan.getSubValue());

构造函数继承
    在子类的构造函数作用环境中执行一次父类的构造函数来实现
    缺点:父类原型无法被继承,是通过call改变函数作用域实现的

        //声明
        function SuperClass(id){
            //共有属性--如果是引用类型(数组,对象)就会有问题
            this.books=["a","b","c"];
            this.id=id;
        }
         //为父类添加共有方法
        SuperClass.prototype.showbooks=function(){
            console.log(this.books);
        }
         //声明子类
        function SubClass(id){
            SuperClass.call(this,id);
        }
        //为子类添加共有方法
        SubClass.prototype.conso=function(){
            console.log("SubClass");
        }
        var instace1=new SubClass(10);
        var instace2=new SubClass(11);
        instace1.books.push("d");
        console.log(instace1.books);
        console.log(instace1.id);
        console.log(instace2.books);
        console.log(instace2.id);
        console.log(instace2.showbooks);//父类原型无法被继承

组合式继承
   把类继承与构造函数组合起来。
   缺点:父类构造函数执行两遍

       //声明
        function SuperClass(id){
            //共有属性--如果是引用类型(数组,对象)就会有问题
            this.books=["a","b","c"];
            this.id=id;
        }
         //为父类添加共有方法
        SuperClass.prototype.showbooks=function(){
            console.log(this.books);
        }
         //声明子类
        function SubClass(id,name){
            SuperClass.call(this,id);
            this.name=name;
        }
        //类式继承 子类原型继承父类
        SubClass.prototype=new SuperClass();
        //为子类添加共有方法
        SubClass.prototype.getName=function(){
            console.log(this.name);
        }
        var instace1=new SubClass(10,"SubClass10");
        var instace2=new SubClass(11,"SubClass11");
        instace1.books.push("d");
        console.log(instace1.books);
        console.log(instace1.id);
        console.log(instace1.getName());
        console.log(instace2.books);
        console.log(instace2.id);
        console.log(instace2.getName());

原型式继承
   对类继承进行封装,过渡对象相当于类继承的子类,只不过在原型式中作为过渡对象出现。
   缺点:类继承的缺点

       //原型式继承
       function createObj(o){
               //声明一个过渡对象
               function F(){};
               //过渡对象原型继承o
               F.prototype=o;
               //返回一个新的过渡对象实例
               return new F();
       }
       
       var obj={
              name:"js book",
              alickbooks:["css book","html book"]
       }
       
        var book_a=createObj(obj);
        book_a.name="book_a";
        book_a.alickbooks.push("book_a");
        console.log(book_a.alickbooks);
        
        var book_b=createObj(obj);
        book_b.name="book_b";
        book_b.alickbooks.push("book_b");
        console.log(book_a.alickbooks);

寄生式继承
   就是对原型式继承的第二次封装,并且在这第二次封装的时候对继承的对象进行扩展,
   这样新创建的对象不仅有父类的属性方法也有自己扩展的属性与方法。
   缺点:类继承的缺点

      //寄生式继承
       function createObj(o){
               //声明一个过渡对象
               function F(){};
               //过渡对象原型继承o
               F.prototype=o;
               //返回一个新的过渡对象实例
               return new F();
       }
       
       var obj={
              name:"js book",
              alickbooks:["css book","html book"]
       }
       
        function createBook(obj){
            //通过原型继承方式创建对象
            var o=new createObj(obj);//这个new要与不要是一样的
            //拓展新方法
            o.getname=function(){
                console.log(name);
            }
            
            //返回拓展后的新对象
            return o;
        }
       
        var book_a=createBook(obj);
        book_a.name="book_a";
        book_a.alickbooks.push("book_a");
        console.log(book_a.alickbooks);
        
        var book_b=createBook(obj);
        book_b.name="book_b";
        book_b.alickbooks.push("book_b");
        console.log(book_a.alickbooks);

寄生组合式继承

       //寄生式继承
       function createObj(o){
               //声明一个过渡对象
               function F(){};
               //过渡对象原型继承o
               F.prototype = o;
               //返回一个新的过渡对象实例
               return new F();
       }
        
        // 
        // 寄生式继承 继承原型
        // 传递参数   subClass   子类
        // 传递参数   superClass 父类
        //
       function inheritPrototype(subClass,superClass){
               //复制一份父类的原型副本保存在变量中
               var p = createObj(superClass.prototype);
               //修正因为重写子类原型导致子类的constructor;
               p.constructor = subClass;
               //设置子类的原型
               subClass.prototype=p;
       }
        
         //定义父类
        function SuperClass(name){
            //共有属性
            this.colors = ["red","blue","green"];
            this.name = name;
        }
         //为父类添加共有方法
        SuperClass.prototype.getName = function(){
            console.log(this.name);
        }
         //定义子类
        function SubClass(name,time){
            //构造函数式继承
            SuperClass.call(this,name);
            //子类新增属性
            this.time = time;
        }
        //寄生式继承父类原型
        inheritPrototype(SubClass,SuperClass);
        //子类原型新增原型方法
        SubClass.prototype.getTime = function(){
            console.log(this.time);
        };
        //创建两个测试方法
        
        var instace1 = new SubClass("js book",2014);
        var instace2 = new SubClass("css book",2013);
        instace1.colors.push("black");
        console.log(instace1.colors);
        console.log(instace2.colors);
        
        console.log(instace1.getTime());
        console.log(instace2.getTime());
        
        console.log(instace1.getName());
        console.log(instace2.getName());

  总结:这篇文章是参考学习的,所有呢,代码中都有注释,希望能够对大家有用。也同时希望大家在休息之余不要忘记学习。

原文地址:https://www.cnblogs.com/xiaoxiaokun/p/7191685.html