Reputation: 20325
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.
Upvotes: 4
Views: 1888
Reputation: 3577
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");
Upvotes: 1
Reputation: 15003
The usual way to do this is to use util.inherits (the linked documentation contains an example that's almost exactly what you want).
Upvotes: 2