ES6 - 将 class 原型附加到单例

ES6 - Attach class prototype to singleton

我想知道将 'new' class 附加到现有实例的最佳方法是什么。

例如:我有一个 'worker' class,它需要 'extend' 到现有的 IPC class 实例,因此它可以通过 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

在这种情况下,'send' 方法将被调用数百万次。

那么在这样的用例中,您会推荐什么?

我也可以在 Worker 实例中再次创建每个函数,然后在该方法中调用 ipc.func(),但这也感觉像是一种反模式。

谢谢

澄清:

我有一个 'host' 工人(主要)..它有一个已经初始化的 IPC (node-ipc) 实例..

当我创建一个 worker 'child' 时,我想使用(已经存在的)父 IPC 实例连接到子 worker..

所以这真的很好,每当我创建一个新的 Worker({ipc:ipc}) 时,我都可以将 worker.prototype 附加到 IPC 实例。这样我就可以 worker.send() 并且 IPC 实例知道它来自主->子通道..

不好意思,我没看懂问题

这可能是您要查找的内容。

这里我们解耦 IPC 对象并将其传递给 Worker 构造函数,然后从实例中简单地委托给 IPC 单例。

正如评论所说,不需要使用 class。

// 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')

如果您真的想要使用worker.theIpcMethod访问ipc方法,您可以使用"class factory",一个创建class 扩展特定值:

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

然后你创建一个具体的 Worker class 或给定的 IPC:

let Worker = WorkerClassFactory(myIpcInstance);

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

当然,您可以创建一次并在整个程序中对其进行实例化,这样您就可以获得一致的 instanceof 行为。


但是! 这真的很奇怪,我真的建议简单地公开一个只读的 属性 并从那里使用它,或者甚至只是将 IPC 接口包装成更易于使用的东西(如果您的 class 只是公开 IPC 的方法,为什么不直接使用 IPC?)。

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

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

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

前面已经说了,composition over inheritance原则也是如此。 Worker 对象应该将 ipc 实例保持为私有 属性 并包装其方法(如果它应该公开其中的一些方法):

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

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