ES6 - 将类原型附加到单例

时间:2016-10-01 11:13:12

标签: javascript ecmascript-6 es6-class

我想知道附加一个新的'最好的方法是什么?类到现有实例。

例如:我有一个'工人'课程,需要扩展'到现有的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(),但这也感觉像是一个反模式。

由于

澄清:

我有一个主持人' worker(main)..它已经初始化了IPC(node-ipc)实例..

当我创建一个工作者孩子时,我想使用(已经存在的)父IPC实例连接到子工作者。

所以这真的很好,当我创建一个新的Worker({ipc:ipc})时,我可以将worker.prototype附加到IPC实例。因此我可以只做worker.send()和IPC实例知道它来自main->子通道..

3 个答案:

答案 0 :(得分:2)

如果确实希望使用ipc访问worker.theIpcMethod方法,则可以使用"类工厂",这是一个创建类的函数扩展特定值:

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 :(得分:2)

正如已经提到的那样,composition over inheritance原则就是这种情况。 Worker对象应该将ipc实例保留为私有属性,如果它应该暴露其中的一些,则包装它的方法:

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

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

答案 2 :(得分: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')