奇怪的Node.jsinheritance

我一直在探索一些Node.js模块,希望能够学习一些我在创build具有类似function的模块时可能错过的东西。 然后我遇到了这个猎犬的代码:

function Hound() { //why this? events.EventEmitter.call(this) } //ok, so inheriting the EventEmitter util.inherits(Hound, events.EventEmitter); 

我知道Node.js中的util.inherits()函数创build一个新的Parent实例,作为文档中陈述的子构造函数的原型:

构造函数的原型将被设置为由superConstructor创build的新对象。

因此,如果我们的构造EventEmitter通过util.inherits()inheritanceEventEmitter ,那么构造函数中的代码是什么?

这只是让你的Hound类成为一个EventEmitter对象。

它给你的EventEmitter实例方法的类。

例如, houndInstance.emit('something')

其他正在监听这些事件的对象可以对其进行响应。


根据您的评论:

 // constructor function Hound() { // equivalent of calling a "super" or "parent" constructor SomeClass.call(this); } 

在JavaScript中, .call(context)是在特定上下文中调用函数的一种手段。 在上面的例子中,我们只是调用SomeClass构造函数,并将this (本例中的Hound类)作为上下文来传递。

从您的意见:

但不util.inherits()已经覆盖了? 还是我错过了什么?

你缺less的是util.inherits()只是inheritance父对象。 它没有设置构造函数来自动调用父对象的构造函数。 在大多数情况下,这是足够的,因为大多数对象在构造函数中不做太多初始化。

但是events.EventEmitter显然在构造函数中做了一些初始化,有一些重要的副作用。 由于原型inheritance不会自动调用父项的构造函数,所以在这种情况下需要手动调用它。 因此events.EventEmitter.call(this)行。


请注意,另一种方法是使用始终调用父级构造函数的模块模式。 这是因为模块模式本身不是inheritance,而是通过滥用mixin / decorator模式来模拟inheritance – 它从父构造器创build一个对象并手动添加属性。 许多人不喜欢模块模式,因为它重复了函数和属性 – 因此他们把它看作是浪费的内存。 另外,这不是正确的inheritance,所以打破了像instanceof这样的东西。