0

I would like to write a constructor function for some work I'm doing in node.js. Amongst other things, I'd like to log the number of instances it creates using an event emitter. At the moment I do this by giving the constructor object a method which is an event emitter. For example:

var EventEmitter = require('events').EventEmitter;

function MyObject() {
    ...
    MyObject.events.emit('createdMyObject')
}

MyObject.events = new EventEmitter();

/* somewhere else... */

MyObject.events.on('createdMyObject', function () {
    // Do something when a new instance is created.
});

What I'd really prefer is for the constructor to more directly emit events, so I could listen for them with something like:

MyObject.on('createdMyObject', function () {
    // Do something when a new instance is created.
});

Is there a way to do this?

Please note, I don't need the instances to be event emitters (there are lots of examples of this when you google it). I want something equivalent to a class method in the parlance of some other OO languages.

qubyte
  • 17,558
  • 3
  • 30
  • 32

3 Answers3

3

Can't you just alias events.on to on? :

// Note: can't use simple function assignment because we need
// the "this" inside on to point to events instead of MyObject

MyObject.on = function (eventType,callback) {
    MyObject.events.on(eventType,callback);
}

it doesn't get rid of MyObjects.events but just provides an alternative method to add event handlers.


Additional answer

If you really want your object to be an event emitter, perhaps what you want is to inherit from an EventEmitter object? If so, simply do regular inheritance:

function MyObject() {
    /*
     * MyObject specific stuff here
     */

    this.emit('createdMyObject');
}

// Now we inherit from an EventEmitter object:
MyObject.prototype = Object.create(EventEmitter.prototype);
slebetman
  • 109,858
  • 19
  • 140
  • 171
  • It'll work, but I'd rather the constructor was a genuine event emitter. – qubyte Nov 07 '12 at 07:36
  • The second answer seems to make instances event emitters, which is not the problem. I really need the constructor to be the emitter so I have only one thing to set listeners on. – qubyte Nov 07 '12 at 08:16
2

This is solved using the non-standard (yet apparently quite commonly used) __proto__ property of the constructor. For example:

var EventEmitter = require('events').EventEmitter;

MyObj = function (a) {
    this.a = a;
    MyObj.emit('new')
}

MyObj.__proto__ = EventEmitter.prototype;

MyObj.on('new', function () {
    console.log('A new myObj was constructed.');
});

var myObj = new MyObj(1);

The expected { a: 1 } object is created, and the creation event triggers the console.log! If anyone can provide an alternative route to this behaviour using something like Object.create, then that is certainly preferable for compliance reasons.

qubyte
  • 17,558
  • 3
  • 30
  • 32
0

This is example, how to construct object that is event emmiter

https://github.com/vodolaz095/kabam-kernel/blob/master/index.js#L17

```

var EventEmitter = require('events').EventEmitter,

function KabamKernel(config) {
  EventEmitter.call(this);
  //a lot of code
}
//a lot of code    
util.inherits(KabamKernel, EventEmitter);
//a lot of code

var kernel = new kabamKernel(configOj);
kernel.on('error',console.error); //kernel is an event emmiter!!!

```

vodolaz095
  • 6,680
  • 4
  • 27
  • 42
  • Sorry, but this is an object. I have no issues constructing event emitter objects. I want to construct an event emitter *function* (as stated in the title). – qubyte Nov 05 '13 at 11:18