Node.js – 从模块发射事件的最佳方法

我一直在玩EventEmitter,但我很困惑我该如何从一个模块实现它。 我已经看到了几种不同的方式,他们似乎都工作。 这里有一些我见过的:

从这里 :

var Twitter = function() {...}; Twitter.prototype = new events.EventEmitter; 

但是在“掌握节点”中,他们这样做:

 function Dog(name) { this.name = name; EventEmitter.call(this); } Dog.prototype.__proto__ = EventEmitter.prototype; 

(为什么你需要打电话?)

然后在我自己的代码中,我尝试了另一种方式:

 function Class() {} Class.prototype = EventEmitter.prototype; 

他们都是以自己的方式inheritanceEventEmitter,所以最简单的解决scheme不是最好的?

你应该使用inheritance的__proto__风格。 这假设你只是为Node编码,或者只支持你喜欢的浏览器 。 此外,如果您关心基础原型的构造函数中的任何逻辑,则需要Base.call(this)

引用基本原型的__proto__技术将确保instanceof运算符正确地标识原型的实例。 子实例的.constructor属性将引用您期望的构造函数。 它还具有不实例化基本原型的新实例的好处。

new Base()风格也将确保instanceof给你正确的答案,但它将运行Base的构造函数。 通常不是问题,但如果您的基础构造函数有必要的参数可能会有问题。 它也将.constructor属性设置为基础构造函数, 而不是后代构造函数 。

将你的的原型设置为基的原型会混淆instanceof因为基类的任何后代也将显示为子实例。

清除泥巴,对不对? 这个例子应该有助于:

 // Base constructor. // A, B, and C will inherit from Base. function Base() { this.name = 'base'; } // new Base() style function A() { Base.call(this); } A.prototype = new Base(); // __proto__ = prototype style function B() { Base.call(this); } B.prototype.__proto__ = Base.prototype; // prototype = protoype style function C() { Base.call(this); } C.prototype = Base.prototype; // create instances var a = new A(); var b = new B(); var c = new C(); // are we who we think we are? console.assert(a instanceof A); console.assert(b instanceof B); console.assert(c instanceof C); // so far so good // do we respect our elders? console.assert(a instanceof Base); console.assert(b instanceof Base); console.assert(c instanceof Base); // we have respect // test to see that Base.call(this) // functioned as expected console.assert(a.name == 'base'); console.assert(b.name == 'base'); console.assert(c.name == 'base'); // ok, good... // but now things get weird console.assert(a instanceof C); console.assert(b instanceof C); // that's not right! a is not C, b is not C! // At least A and B do not confuse identities console.assert(!(a instanceof B)); console.assert(!(b instanceof A)); console.assert(!(c instanceof A)); console.assert(!(c instanceof B)); // so we've determined that style C is no good. // C confuses the inheritance chain. // B is the winner. // Why? Only B passes this test console.assert(b.constructor == B); // a and c's constructors actually point to the Base constructor console.assert(a.constructor == Base); console.assert(c.constructor == Base); // Word B. 

Node有一个库函数util.inherits,比接受的答案稍微简单一些。 下面的代码从v0.8.12文档修改。

 var util = require("util"); var events = require("events"); function MyStream() { events.EventEmitter.call(this); } util.inherits(MyStream, events.EventEmitter);