2017-02-15 112 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類只是隱藏良好的原型遺傳的句法糖。所以他們基本上是構造函數的一些細節。 –