你应该如何从节点中的 EventEmitter 继承? [英] How should you inherit from EventEmitter in node?

查看:42
本文介绍了你应该如何从节点中的 EventEmitter 继承?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读这篇小文章以了解从 EventEmitter,但我有点困惑.

I was reading over this small article to understand inheriting from EventEmitter, but I'm a little confused.

他这样做:

function Door() {
    events.EventEmitter.call(this);
    this.open = function() {
        this.emit('open');
    };
}
Door.prototype.__proto__ = events.EventEmitter.prototype;

https://gist.github.com/chevex/7646362

为什么他用自己的构造函数的this手动调用EventEmitter的构造函数?还有,他为什么把他的构造器的原型设置为EventEmitter的原型?这让我非常困惑.

Why does he manually invoke the EventEmitter constructor with his own constructor's this? Also, why does he set the prototype of his contsructor's prototype to the prototype of EventEmitter? That's super confusing to me.

然后有人在评论中建议他这样做,这看起来更优雅:

Then someone in the comments suggested he do this instead, which seemed more elegant:

function Door() {
    events.EventEmitter.call(this);
    this.open = function () {
      this.emit('open');
    }
}
util.inherits(Door, events.EventEmitter);

https://gist.github.com/chevex/7646447

这似乎比其他方式更干净,尽管这可能只是因为我无法理解最初发生的事情.如果 util.inherits 和第一个例子做同样的事情,我不会感到惊讶.

This seems WAY cleaner than the other way, though that's probably just because I fail to understand what's going on in the first instance. I would not be surprised if util.inherits is doing the same thing as the first example.

第二个至少对我来说有点意义,但我仍然不明白他们为什么不这样做:

The second one at least makes a little sense to me, but I still don't understand why they don't just do this:

function Door() {
    this.open = function () {
      this.emit('open');
    }
}
Door.prototype = new events.EventEmitter();

https://gist.github.com/chevex/7646524

谁能向我解释所有这些方法之间的区别,以及为什么在前两种方法中他们在 EventEmitter 构造函数上调用 .call(this) ?我在尝试示例时省略了该行,但它们仍然有效.

Can anyone explain to me what the differences between all of these approaches is and why in the first two they invoke .call(this) on the EventEmitter constructor? I omitted that line while trying out the examples and they still worked.

推荐答案

第三个例子通常是正确的:它为所有人创建了一个 EventEmitter 实例 门实例.

The third example is not generally correct: that creates one single EventEmitter instance for all door instances.

让我们想象一个简单的案例:

Let's imagine a simple case:

var Foo = function() {
    // each Foo instance has a unique id
    this.id = Math.random();
}
Foo.prototype.doFoo = function() { console.log("Foo!"); }

假设我们要创建一个继承自 FooBar 构造函数并添加一些新属性.如果您遵循最后一个示例:

Suppose we want to create a Bar constructor that inherits from Foo and adds some new properties. If you follow your final example:

var Bar = function() {
    this.something = 5;
}
Bar.prototype = new Foo();

这是错误的,因为所有 Bar 实例将具有相同的 id 属性.相反,我们必须为每个实例调用父构造函数:

This is wrong because all Bar instance will have the same id property. Instead, we must call the parent constructor for each instance:

var Bar = function() {
    Foo.call(this);  // set unique `id` on `this`
    this.something = 5;
}
Bar.prototype = Object.create(Foo.prototype);

请注意,这里的最后一行与 Bar.prototype.__proto__ = Foo.prototype; 相同,因为 Object.create 创建了一个新对象,其 __proto__ 设置为 Object.create 参数.

Note that the final line here is the same as Bar.prototype.__proto__ = Foo.prototype; because Object.create creates a new object whose __proto__ is set to the Object.create argument.

这篇关于你应该如何从节点中的 EventEmitter 继承?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆