Node.js - 从模块发出事件的最佳方法

发布于 2024-11-27 03:21:58 字数 744 浏览 0 评论 0原文

我一直在使用 EventEmitter,但我对应该如何从模块中实现它感到困惑。我见过几种不同的方法,它们似乎都有效。以下是我见过的一些:

来自 此处

var Twitter = function() {...};

Twitter.prototype = new events.EventEmitter;

但随后在 "Mastering Node" 他们这样做:(

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

Dog.prototype.__proto__ = EventEmitter.prototype;

为什么你需要.call它?)

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

function Class() {}

Class.prototype = EventEmitter.prototype;

它们都只是以自己的方式继承 EventEmitter,所以最简单的解决方案不是最好的吗?

I've been playing around with the EventEmitter, but I'm confused about how exactly I should implement it from a module. I've seen a few different ways, and they all seem to work. Here are a few I've seen:

From here:

var Twitter = function() {...};

Twitter.prototype = new events.EventEmitter;

But then in "Mastering Node" they do it this way:

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

Dog.prototype.__proto__ = EventEmitter.prototype;

(why would you need to .call it?)

And then in my own code I tried yet another way:

function Class() {}

Class.prototype = EventEmitter.prototype;

They're all just inheriting from EventEmitter in their own way, so wouldn't the simplest solution be the best?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

乖乖哒 2024-12-04 03:21:58

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);

Node has a library function, util.inherits, that is slightly more straightforward than the accepted answer. Code below is modified from the v0.8.12 docs.

var util = require("util");
var events = require("events");

function MyStream() {
  events.EventEmitter.call(this);
}

util.inherits(MyStream, events.EventEmitter);
温柔戏命师 2024-12-04 03:21:58

您应该使用 __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.

You should use the __proto__ style of inheritance. This assumes you're coding solely for Node, or only supporting your favorite browsers. Also, Base.call(this) is necessary if you care about any logic in the constructor of your base prototype.

The __proto__ technique to reference a base prototype will ensure that the instanceof operator correctly identifies instances of the prototype. The .constructor property of instances of the child class will reference the constructor you expect it to. It also has the benefit of not instantiating a new instance of the base prototype.

The new Base() style will also ensure that instanceof gives you the correct answer, but it will run the constructor for Base. Generally not an issue, but can be problematic if your base constructor has required arguments. It will also set the .constructor property to the base constructor, not the descendant constructor.

Setting the prototype of your class to the prototype of the base class will confuse instanceof as any descendants of the base will also appear to be instances of the child.

Clear as mud, right? This example should help:

// 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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文