Given an arbitrary object, I want to make it an EventEmitter:
var obj = {}
// mixin eventemitter
obj.on('event', ...)
obj.emit('event')
Also, when I type in obj, I don't want it to show the EventEmitter methods as methods. ex via CLI:
> obj
{}
Thus, right now I'm doing:
function mixinEventEmitter(obj) {
obj.__proto__ = EventEmitter.prototype
return obj
}
But people say using __proto__
is an anti-pattern: Node.js - inheriting from EventEmitter
Am I doing it correctly? Do you have a better way of doing this? Thanks.
The usual way to do this is to use util.inherits (the linked documentation contains an example that's almost exactly what you want).
The problem with __proto__
isn't that you're using prototypes instead of constructors. The issue is that it's the wrong way to use prototypes. But you don't want a prototype. You want a mixin. Using __proto__
is a hack that avoids doing the work of creating a mixin. If you want a mixin, you have to do it manually, without prototypes.
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");