美文网首页
前端 mixin 的源码实现

前端 mixin 的源码实现

作者: 泰然自若_750f | 来源:发表于2020-04-02 14:54 被阅读0次

    在vue 和React的开发中我们会经常使用一个方法 mixin,可以将多个Class上方法合并到一个属性中。下面我们简易实现一下该功能。

    一:首先我们需要明确几个概念

    1:类的所有方法都定义在类的prototype属性上面。

       //定义类
    class Point {
      constructor(x, y) {
        this.x = x;
        this.y = y;
      }
    
      toString() {
        return '(' + this.x + ', ' + this.y + ')';
      }
    }
    //在控制上打印,toString 方法 在原型中。
    Point.prototype
    //{constructor: ƒ, toString: ƒ}
    //constructor: class Point
    //toString: ƒ toString()
    //__proto__: Object
    point.hasOwnProperty('x'); //true
    point.hasOwnProperty('y'); //true//true
    point.hasOwnProperty('toString'); //false
    point.__proto__.hasOwnProperty('toString'); //true
    Point.prototype.hasOwnProperty('toString'); //true
    

    2:了解Object 上的几个方法
    Object.getOwnPropertyNames():方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
    Object.getOwnPropertyDescriptor(): 方法返回指定对象上一个自有属性对应的属性描述。
    Object.defineProperty(): 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

    二:下面是实现mixin 的方法。

       function mixin(constructor)
                    {
                        return function(...args){
                            //遍历需要合并的对象
                            for(let arg of args)
                            {
                                //遍历 合并对象原型上的属性
                               for(let key of Object.getOwnPropertyNames(arg.prototype))
                               {
                                   //除去构造函数方法 和 constructor存在的属性,避免被覆盖
                                   if(key!='constructor' && !Object.getOwnPropertyDescriptor(constructor.prototype,key))
                                   {
                                       //合并
                                       Object.defineProperty(constructor.prototype,key,Object.getOwnPropertyDescriptor(arg.prototype,key))
                                   }
                               }
    
                            }
    
                        }
    
                    }
    

    三:下面定义几个类测试一下是否生效

      class A{
                        constructor(data){
                            this.data=data;
    
                        }
                          
                          getA(){
                              return this.data;
    
                          }
                    }
                     class B{
                        constructor(data){
                            this.data=data;
    
                        }
                          
                          getB(){
                              return this.data;
    
                          }
                    }
                     class C{
                        constructor(data){
                            this.data=data;
    
                        }
                          
                          getC(){
                              return this.data;
    
                          }
                    }
          mixin(A)(B,C);
          //控制台打印
          A.prototype //{constructor: ƒ, getA: ƒ, getB: ƒ, getC: ƒ}
    

    相关文章

      网友评论

          本文标题:前端 mixin 的源码实现

          本文链接:https://www.haomeiwen.com/subject/ggrxphtx.html