2017-02-15 66 views
8

在带有一些实例变量和方法的ES6类中,如何添加一个mixin?我在下面给出了一个例子,但我不知道mixin对象的语法是否正确。如何将mixin添加到ES6 JavaScript类?

class Test { 
    constructor() { 
    this.var1 = 'var1' 
    } 
    method1() { 
    console.log(this.var1) 
    } 
    test() { 
    this.method2() 
    } 
} 

var mixin = { 
    var2: 'var2', 
    method2: { 
    console.log(this.var2) 
    } 
} 

如果我运行(new Test()).test(),它将为什么我需要将混入变量和方法添加到类失败,因为有一个在类中没有method2,因为它是在混合料搅拌,这就是。

我看到有一个lodash mixin函数https://lodash.com/docs/4.17.4#mixin,但我不知道如何将它与ES6类一起使用。我很好地使用lodash解决方案,甚至没有库提供混合功能的普通JS。

+0

http://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/ – zloctb

回答

13

Javascript的对象/属性系统比大多数语言更具动态性,所以向对象添加功能非常简单。由于函数是第一类对象,因此它们可以以完全相同的方式添加到对象中。 Object.assign是将一个对象的属性添加到另一个对象的方式。 (其行为在许多方面与_.mixin相当。)

Javascript中的类只是语法糖,它使添加构造函数/原型对变得简单明了。功能没有从ES6之前的代码改变。

您可以将属性添加到原型:

Object.assign(Test.prototype, mixin); 

你可以在构造函数中添加它来创建的每个对象:

constructor() { 
    this.var1 = 'var1'; 
    Object.assign(this, mixin); 
} 

你可以在构造函数中根据条件将其添加:

constructor() { 
    this.var1 = 'var1'; 
    if (someCondition) { 
     Object.assign(this, mixin); 
    } 
} 

或者您可以在创建后将其分配给对象:

let test = new Test(); 
Object.assign(test, mixin); 
+1

@ user779159这个人挺直的。所以试试他提出的建议。 –

+0

@lonesomeday将它添加到对象本身的原型之间有什么区别?我认为在声明方法时最好在原型上做,因为那么所有对象都共享相同的函数,而不是它们都有自己的函数来执行相同的操作。这是否也适用于这种mixin技术,将其应用于原型比对象更有效? – user779159

+1

@ user779159该函数将只存在一次。只有当你再次声明该函数时,才会创建第二个函数。 (例如,如果你有一个修饰器函数每次运行时都会创建一个新函数)。 – lonesomeday

1

您应该看看Object.assign()。总得是这个样子:

Object.assign(Test.prototype, mixin); 

这将确保从mixin所有方法和属性将被复制到Test构造函数的原型对象。

+0

有没有办法来调用从内'class'本身? – user779159

+0

这是非常值得怀疑的。这是因为ES6类只是隐藏良好的原型遗传的句法糖。所以他们基本上是构造函数的一些细节。 –