2016-12-27 39 views
0

我有這個簡單的類:在構造函數之前運行鏈接方法?

class Foo { 
 
    constructor() { 
 
    this.init(); 
 
    return this; 
 
    } 
 

 
    init() { 
 
    this.onInit(); 
 
    } 
 

 
    onInit(callback) { 
 
    this.onInit =() => callback(); 
 
    return this; 
 
    } 
 
} 
 

 
new Foo().onInit(() => console.log('baz'));

這顯然是有缺陷的,因爲它會調用initonInit方法能夠定義onInit屬性/回調。

如何在不改變界面的情況下使這項工作成爲可能?

+2

如果將「init」定義爲「當構造函數正在執行時」,那麼將回調設置爲構造函數的鏈接事件(根據定義在*構造函數後執行*)是簡單的矛盾,並且沒有合理的解決方法那。 – deceze

+0

我明白了你的觀點,事實是我的庫是'new Something()。onCreate()。onUpdate()',它是有道理的,因爲它創建了實例,然後在實例之後設置你想要做的事情已創建(以及何時更新)。所以,「語法」,這是有道理的,我想找到一種方法來保持它.. –

+1

*語法*如果我們可以寫*「計算機,喝杯茶」*,但實際上我們不得不屈服於編程語言的規則......;) – deceze

回答

3

我如何以不改變接口這項工作?

你不能,接口本質上是有缺陷的。這真的是你的問題的答案。


在繼續,雖然,以「我能做些什麼,而不是」:

如果你需要有一個初始化過程中調用回調函數,你需要將它傳遞給構造函數,而不是單獨爲onInit方法。

class Foo { 
    constructor(callback) { 
    this.onInit =() => { 
     callback(); // Call the callback 
     return this; // Chaining seemed important in your code, so... 
    }; 
    // Note: Constructors don't return anything 
    } 
} 

new Foo(() => console.log('baz')); 

在你所說的評論:

我明白你的意思,但事實是,我的圖書館是new Something().onCreate().onUpdate()

這聽起來像你可能想採用builder pattern代替:

class Foo { 
    constructor(callbacks) { 
     // ...use the callbacks here... 
    } 
    // ... 
} 
Foo.Builder = class { 
    constructor() { 
     this.callbacks = {}; 
    } 
    onCreate(callback) { 
     this.callbacks.onCreate = callback; 
    } 
    onUpdate(callback) { 
     this.callbacks.onUpdate = callback; 
    } 
    // ... 
    build() { 
     // Validity checks here, do we have all necessary callbacks? 
     // Then: 
     return new Foo(this.callbacks); 
    } 
}; 

let f = new Foo.Builder().onCreate(() => { /*...*/}).onUpdate(() => { /*... */}).build(); 

...雖然是公平的,建造者模式的一個很大的優勢(雖然不是全部)可以通過JavaScript的只是傳遞對象爲constructor直接做您的驗證那裏,如實現:

let f = new Foo({ 
    onCreate:() => { /*...*/}, 
    onUpdate:() => { /*...*/} 
}); 
+0

謝謝,我將在構造函數選項中移動所有內容,與語言作鬥爭是沒用的:/ –

1

假設onInit應該是某種類型的鉤子,每當一個對象被實例化時都會被同步調用,你不能在實例級別上解決這個問題。

您可以onInit靜態函數,就像這樣:

class Foo { 
 
    constructor() { 
 
    // whatever 
 
    Foo.onInit(); 
 
    } 
 

 
    static onInit() {} // empty default 
 
} 
 

 
Foo.onInit =() => console.log('baz'); // Override default with your own function 
 
const f = new Foo(); 
 
const f2 = new Foo();

+0

謝謝,但這樣做,我需要將命令分成多行,難道你沒有想法把它作爲一個鏈接命令列表?我猜可能是黑客.. –

+0

當你有命令的基礎時,已經太晚了,所以沒有。恐怕不可能。 –

相關問題