zoukankan      html  css  js  c++  java
  • js中实现继承的几种方式

    继承

    JS中继承的概念:

    • 通过【某种方式】让一个对象可以访问到另一个对象中的属性和方法,我们把这种方式称之为继承 并不是所谓的xxx extends yyy

    为什么要使用继承?

    • 有些对象会有方法(动作、行为),而这些方法都是函数,如果把这些方法和函数都放在构造函数中声明就会导致内存的浪费
        function Person(){
            this.say=function(){
                console.log("你好")
            }
        }
        var p1=new Person();
        var p2=new Person();
        console.log(p1.say === p2.say);   //false
    

    继承的第一种方式:原型链继承1

        Person.prototype.say=function(){
            console.log("你好")
        }
    
    • 缺点:添加1、2个方法无所谓,但是如果方法很多会导致过多的代码冗余

    继承的第二种方式:原型链继承2

        Person.prototype = {
            //切记不能忘记
            constructor:Person,
            say:function(){
                console.log("你好");
            },
            run:function(){
                console.log("正在进行百米冲刺");
            }
        }
    
    • 注意点:
    • a、一般情况下,应该先改变原型对象,再创建对象
    • b、一般情况下,对于新原型,会添加一个constructor属性,从而不破坏原有的原型对象的结构

    继承的第三种方式:拷贝继承(混入继承:mixin)

    • 场景:有时候想使用某个对象中的属性,但是又不能直接修改它,于是就可以创建一个该对象的拷贝
    • 实际运用:
      • jquery:$.extend:编写jquery插件的必经之路
        • 基于jquery封装一个表格控件
        var o1={ age:2 };
    
        var o2 = o1;
        o2.age=18;      
        //1、修改了o2对象的age属性
        //2、由于o2对象跟o1对象是同一个对象
        //3、所以此时o1对象的age属性也被修改了
    
        var o3={gender:"男",grade:"初三",group:"第五组",name:"张三"};
        var o4={gender:"男",grade:"初三",group:"第五组",name:"李四"};
        //上述代码中,如果使用拷贝继承对代码进行优化会非常和谐
    
        //实现拷贝继承:
        //1、已经拥有了o3对象
        //2、创建一个o3对象的拷贝(克隆):for...in循环
        
    
        //3、修改克隆对象,把该对象的name属性改为"李四"
        
    
    • 实现1:
        var source={name:"李白",age:15}
        var target={};
        target.name=source.name
        target.age=source.age;
    
    • 浅拷贝和深拷贝

      • 浅拷贝只是拷贝一层属性,没有内部对象
      • 深拷贝其实是利用了递归的原理,将对象的若干层属性拷贝出来
          var students=[
              {name:"",age:""},
              {name:"",age:""}
          ]
      
    • 上面的方式很明显无法重用,实际代码编写过程中,很多时候都会使用拷贝继承的方式,所以为了重用,可以编写一个函数把他们封装起来:

        function extend(target,source){
            for(key in source){
                target[key]=source[key];
            }
            return target;
        }
        extend(target,source)
    
    • 由于拷贝继承在实际开发中使用场景非常多,所以很多库都对此有了实现

      • jquery:$.extend
    • es6中有了 <对象扩展运算符> 仿佛就是专门为了拷贝继承而生:

      • 优点:简单的令人发指
        var source={name:"李白",age:15}
        //让target是一个新对象,同时拥有了name、age属性
        var target={ ...source }
        
        var target2={ ...source,age:18 }
    

    继承的第四种方式:原型式继承:(道格拉斯在蝴蝶书中提出来的)

    • 场景:
      • a、创建一个纯洁的对象:对象什么属性都没有
      • b、创建一个继承自某个父对象的子对象
            var parent={ age:18,gender:"男"};
            var student=Object.create(parent);
            //student.__proto__===parent
        
    • 使用方式:
      • 空对象:Object.create(null)
          var o1={ say:function(){} }
          var o2=Object.create(o1);
      

    继承的第五种方式:借用构造函数实现继承

    • 场景:适用于2种构造函数之间逻辑有相似的情况
    • 原理:函数的call、apply调用方式
    function Animal(name,age,gender){
        this.name=name;
        this.age=age;
        this.gender=gender;
    }
    function Person(name,age,gender,say){
        this.name=name;
        this.age=age;
        this.gender=gender;
    
        this.say=function(){
    
        }
    }
    
    • 局限性:Animal(父类构造函数)的代码必须完全适用于Person(子类构造函数)

    • 以上代码用借用构造函数实现

    function Animal(name,age){
        this.name=name;
        this.age=age;
    }
    function Person(name,age,address){
        Animal.call(this,name);
        //this.name=name;
        //this.age=age;
        this.address=address;
    }
    
    • 寄生继承、寄生组合继承
  • 相关阅读:
    奇数阶魔方问题
    《DSP using MATLAB》示例9.3
    《DSP using MATLAB》示例9.2
    《DSP using MATLAB》示例9.1
    找个目标很重要
    《DSP using MATLAB》示例Example 8.30
    《DSP using MATLAB》示例Example 8.29
    《DSP using MATLAB》示例Example 8.28
    《DSP using MATLAB》示例Example 8.27
    《DSP using MATLAB》示例Example 8.26
  • 原文地址:https://www.cnblogs.com/sunhang32/p/11838821.html
Copyright © 2011-2022 走看看