2016-10-01 18 views
1

我在想什麼最好的方法是將「新」類附加到現有實例。ES6 - 將類原型附加到單身人士

例如:我有一個'worker'類,它需要'擴展'到現有的IPC類實例,因此它可以通過ipc通道進行通信。

class Worker { 
    constructor(ipc) { 
     this.__proto__ = ipc; 
     this.__proto__.constructor = Worker; 
    } 
} 

,然後我可以這樣使用它:

const worker = new Worker(myCurrentIpc); 
worker.send('blabla') /* Calls super instance ipc method */ 

這是不好的做法,因爲它殺死性能.. https://developer.mozilla.org/nl/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf

在這種情況下,「發送」方法被稱爲數百萬次。

所以在這樣的用例中,你會推薦什麼?

我也可以在Worker實例中再次創建每個函數,然後在該方法中調用ipc.func(),但那也感覺像是反模式。

感謝

澄清:

我有一個 '主' 工人(主要)..這有一個已經初始化IPC(節點-IPC)實例..

當有史以來我創建一個工人'孩子',我想使用(已經存在的)父IPC實例連接到子工。

所以這將是非常好的,th在我創建一個新的Worker({ipc:ipc})時,我可以將worker.prototype附加到IPC實例。因此,我可以執行worker.send(),並且IPC實例知道它從main- >子頻道..

+0

是'ipc'本身另一個類,或者只是一個普通的對象或類實例? – Kroltan

+0

ipc是已經初始化的類實例 – DutchKevv

+0

您的父級工作者 - 子工作者關係聽起來不像子類關係。你應該在這裏贊成組合繼承。 – Bergi

回答

2

正如已經提到的那樣,composition over inheritance原理就是這種情況。工人對象應該保持ipc實例作爲私有財產,如果它應該揭露一些他們的包裹它的方法:

class Worker { 
    constructor(ipc) { 
    this.ipc = ipc; 
    } 

    send(...args) { 
    return this.ipc.send(...args); 
    } 
} 
1

我的不好,我不明白這個問題。

這可能會多一點你在找什麼。

這裏我們解耦IPC對象並將它傳遞給Worker構造函數,然後從實例中簡單地委派給IPC單例。

正如評論所說,不需要使用類。

// here is a singleton with a single static method. using class in not really 
 
// neccasary here, you could just use an object with a single propery 
 
class IPC { 
 
    static send(val) { 
 
    console.log('IPC::send', val) 
 
    } 
 
} 
 

 
class Worker { 
 
    // constructor takes the ipc as a variable and saves it to itself 
 
    constructor(ipc) { 
 
    this.ipc = ipc 
 
    } 
 
    // the send method simply calls the ipc send function 
 
    send(val) { 
 
    this.ipc.send(val) 
 
    } 
 
} 
 

 
// create a new worker 
 
const worker = new Worker(IPC); 
 

 
worker.send('blabla')

+1

感謝代碼示例@ synthet1c,但是然後IPC不是一個單獨的,而是一個新的類。我想將一個'new'實例附加到一個singeton /現有的實例 – DutchKevv

+0

您不應該對singleton使用'class' 。如果你讓它成爲一個類,使用'new'創建實例,如果你想要一個單例,那麼使用一個對象字面值。 – Bergi

2

如果你真的worker.theIpcMethod訪問ipc方法,你可以使用一個「類工廠」,可帶來特定值的類的功能:

function WorkerClassFactory(ipc) { 
    return class Worker extends ipc { 
     //contents of Worker class here 
    } 
} 

然後您創建一個具體的Worker類或給定的IPC:

let Worker = WorkerClassFactory(myIpcInstance); 

//then somewhere 
let worker_instance = new Worker(); 
worker_instance.doStuff(); 

當然,您可以創建一次並在整個程序中實例化它,以便獲得一致的instanceof行爲。


但是!這是一件非常奇怪的事情,我真的建議僅僅公開一個只讀屬性並從那裏使用它,或者甚至只是將IPC接口包裝成更簡單的使用方式(如果你的類只是暴露IPC的方法,爲什麼不直接使用IPC?)。

class Worker { 
    constructor(ipc) { 
     this._ipc = ipc; 
    } 

    get ipc() { 
     return this._ipc; 
    } 
} 

new Worker(ipc).ipc.send("asdasdasd"); 
+1

感謝代碼示例@Kroltan ...我很放心,你和synthet1c都在推動ipc成爲類內變量的方向..開始感覺自己像是在推動繼承thingy遠 – DutchKevv

+0

@DutchKev是的,這樣做是對原型繼承的濫用。這也是不一致的,因爲如果你用'ipc'的相同值調用'WorkerClassFactory'兩次,那個類的實例不一定是'instanceof'那個worker。當然,工廠可以緩存它的輸出,但這完全是一個有問題的解決方法。 – Kroltan

+2

@DutchKev這是[繼承構成](https://en.wikipedia.org/wiki/Composition_over_inheritance)原理。這不是一個經驗法則,但在這裏完全適用。 – estus