美文网首页
前端 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