简体   繁体   中英

node.js EventEmitter and iife pattern

I have a question specific a bit to inheritance in javascript rather than node.js:

// foo.js
var events = require('events');
var util = require('util');

var Foo = (function(){
    var foo = {};
    events.EventEmitter.call(foo);
    foo.init = function(){
        foo.emit('bar');
    };

    util.inherits(parser, events.EventEmitter);

    return { 
        bind: foo.init,
        on: foo.on // I suppose this resolves to event emitter's on method
    };

}());

module.exports = Foo;

Then, when i simply try to call (say in main.js):

var foo = require('./foo.js');

foo.on('bar', function(){ ... });

An error is generated before i even call foo.init(); :

foo.on('bar', function(){ ... })
       ^
TypeError: Property 'on' of object #<Object> is not a function

Isn't it possible to inherit from EventEmitter when I chose to code in IIFE pattern? Or my error is related something else?

If you want to keep this pattern, and you have a good reason for not using prototypal inheritance like this:

FooConstuctor.prototype = new events.EventEmitter();

Then, if all you need from the EventEmitter is the on method, you can just add:

Foo.on = events.EventEmitter.prototype.on;

Right after you create Foo .

You don't get the on method on Foo just by invoking EventEmitter 's constructor on Foo because the on method isn't attached to EventEmitter objects in the constructor.

The reason for that is probably that it's usually considered bad practice to assign methods to your objects in their constructor, because then, a new function instance is created for each object instance which is unnecessary usually and wasteful, and methods created like this aren't directly assigned to the prototype, which can be misleading for other developers planning to extend your "class".

If I need an object that acts like an EventEmitter with the module pattern I prefer the following:

var foo = function () {

  var ee = new EventEmitter();

  /* custom logic */

  return {
    on: ee.on.bind(ee),
    emit: ee.emit.bind(ee),
  }

};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM