你应该如何从节点中的 EventEmitter 继承? [英] How should you inherit from EventEmitter in node?
问题描述
我正在阅读这篇小文章以了解从 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!"); }
假设我们要创建一个继承自 Foo
的 Bar
构造函数并添加一些新属性.如果您遵循最后一个示例:
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屋!