4

给定一个任意对象,我想让它成为一个 EventEmitter:

var obj = {}
// mixin eventemitter
obj.on('event', ...)
obj.emit('event')

此外,当我输入 obj 时,我不希望它将 EventEmitter 方法显示为方法。通过 CLI:

> obj
{}

因此,现在我正在做:

function mixinEventEmitter(obj) {
  obj.__proto__ = EventEmitter.prototype
  return obj
}

但是人们说 using__proto__是一种反模式:Node.js - 从 EventEmitter 继承

我做得对吗?你有更好的方法吗?谢谢。

4

2 回答 2

2

执行此操作的常用方法是使用util.inherits(链接文档包含一个几乎正是您想要的示例)。

于 2012-09-26T13:03:19.843 回答
1

问题__proto__不在于您使用的是原型而不是构造函数。问题是使用原型的方法是错误的。但是你不想要原型。你想要一个mixin。Using__proto__是一种避免创建 mixin 工作的技巧。如果你想要一个 mixin,你必须手动完成,没有原型。

var EventEmitter = require("events").EventEmitter,
    obj = {};

function emitter(obj) {
    // copy EventEmitter prototype to obj, but make properties
    // non-enumerable
    for (var prop in EventEmitter.prototype) {
        Object.defineProperty(obj, prop, {
            configurable: true,
            writable: true,
            value: EventEmitter.prototype[prop]
        });
    }

    // also, make sure the following properties are hidden
    // before the constructor adds them
    ["domain", "_events", "_maxListeners"].forEach(function(prop) {
        Object.defineProperty(obj, prop, {
            configurable: true,
            writable: true,
            value: undefined
        });
    });

    // call EventEmitter constructor on obj
    EventEmitter.call(obj);

    // return the obj, which should now function as EventEmitter
    return obj;
}

emitter(obj);
obj.on("event", console.log.bind(console));
obj.emit("event", "foo");
于 2015-04-18T20:19:14.960 回答