最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • js实现继承的最佳方案,探索企业级的解决方案 - 掘金

    正文概述 掘金(梦想敲木鱼)   2021-11-16   931

    js实现继承的方式

    1. 借用构造函数的方式
     function Parent(){
         var opt = arguments[0];
         this.name = opt.name;
     }
     function Child(opt){
         Parent.call(this,opt)
         this.age = opt.age;
     }
    

    借用构造函数的方式是在子类构造函数中执行父类构造函数的函数体,且将上下文修改为实例创建的新对象,这种方式可以实现给父类构造函数传递参数,但是这种方式的弊端是,必须在构造函数中定义方法和属性,而且子类也不能访问父类原型上的属性和方法,所以这种方式不能单独使用。

    2. 基于原型链继承的方式和优缺点
        function SuperType() {
            this.name = 'super';
            this.colors = ["red", "blue", "green"];
        }
        function SubType() {}
        // 继承 SuperType
        SubType.prototype = new SuperType();
        let instance1 = new SubType();
        instance1.colors.push("black");
        console.log(instance1.colors,instance1.name); // "red,blue,green,black" sub
        let instance2 = new SubType();
        console.log(instance2.colors,instance2.name); // "red,blue,green,black" super
    

    通过new SuperType()生成的SuperType实例对象变成了SubType的原型对象,那么这个实例对象上的属性和方法,都变成了子类原型对象上的属性和方法,会被所有的子类实例共享的,当子类实例操作时,引用类型的值会被改变,原始类型的值不会被改变。原始值会改变是因为,当我们通过object[name]操作属性时,如果这个对象没有,会给这个对象新增一个该属性,所以不会去修改原型上的同名属性。

    优缺点:
    • 这种方式不仅继承了父类构造方法和属性,也继承了父类原型对象。
    • 缺点一是这种方式父类构造方法中的所有方法和属性都会被子类实例共享,如若子类实例修改引用类型的值会,会影响所有子类实例。
    • 缺点二是子类型在实例化时不能给父类型的构造函数传参。

    但是我们一般只会继承父类的原型对象,对于构造属性和方法,我们最终希望是生成实例属性和方法,所以我们应该只继承原型。

          function SuperType() {
            this.name = 'super';
            this.colors = ["red", "blue", "green"];
           }
          SuperType.prototype.flag = true;
        function SubType() {}
        // 继承 SuperType
        SubType.prototype = SuperType.prototype;
        SubType.prototype.flag = false;
        let instance1 = new SubType();
        console.log(instance1.flag); // false
        let instance2 = new SuperType();
        console.log(instance2.flag); // false
    
    

    通过 SubType.prototype = SuperType.prototype,我们只继承了父类的原型对象,但是这样也会产生一个问题,子类和父类的原型指向同一个引用,当子类对原型进行操作时,会同时修改了父类的原型。继承不应该向上影响,所以为了解决这个问题,我们需要一个中间对象来做一个缓冲:

    // 优化这种继承方式,我们可以使用中间对象来做一个缓冲的方式来解决
    function Super(){
         this.Mskill  = 'Java';
     }
     Super.prototype = {
         name : 'super',
         age : 100
     }
    
     function Buffer(){};
     Buffer.prototype = Super.prototype;
     var buffer = new Buffer();
     Child.prototype = new Buffer();
     function Child(){
         this.skill = 'js';
     }
    

    这样就将子类的原型和父类的原型分隔开来了,我们对子类的原型对象进行操作,不会影响父类的原型,而且也继承了父类的原型。为了解决重写原型导致constructor丢失的问题,我们也需要将子类的constructor属性重新只会子类构造函数,可以自定义一个指向父类构造的属性。

    这种方式的企业级封装方案:

    // 继承的优化写法,通过封装继承的方法,实现任意两个类之间的继承
     function inherit(Target,Origin){
         var Buffer = function(){};
         Buffer.prototype = new Origin();
         var buffer = new Buffer();
         Target.prototype = buffer;
         Target.prototype.constructor = Target;
         Target.prototype.super_class = Origin;
     }
    
    3.寄生式组合方式
     function Parent(){
         var opt = arguments[0];
         this.name = opt.name;
     }
     function Child(opt){
         Parent.call(this,opt)
         this.age = opt.age;
     }
    inherit(Child,Parent);
    

    这种方案是最优的解决方案了,不仅实现了原型链的继承,而且通过借用构造函数的方法,将父类的构造方法和属性,生成到了子类实例上,还能给父类的构造函数传递参数。

    4. Object.create方法

    上述方案中,我们是创建一个缓冲对象来隔离父类原型和子类原型,创建缓冲对象是通过创建一个空的构造函数,将这个构造函数的原型执行父类原型,然后实例化这个空的构造函数来实现的。但我们有现成的方法来帮助我们完成这一操作,Object.create方法,参数1接收一个对象,作为生成对象的原型。所以我们可以通过这个方法来改写上述的继承方案:

         function inherit(Target,Origin){
         var _prototype = Object.create(Origin.prototype);  //创建对象
         _prototype.constructor = Target;  //增强对象
         _prototype.super_class = Origin;
         Target.prototype = _prototype;  //赋值实现继承
     }
    

    至此,js的继承方式我们已经全部总结了一遍,寄生式组合方式是引用类型继承的最佳方案。


    起源地下载网 » js实现继承的最佳方案,探索企业级的解决方案 - 掘金

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元