1

我一直在研究一些 Node.js 模块,希望能学到一些我在创建具有类似功能的模块时可能会错过的东西。然后我从Hound发现了这段代码:

function Hound() {
    //why this?
    events.EventEmitter.call(this)
}

//ok, so inheriting the EventEmitter
util.inherits(Hound, events.EventEmitter);

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

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

EventEmitter那么如果我们的构造函数是通过继承util.inherits()的,那么构造函数中的代码是干什么用的呢?

4

2 回答 2

1

它只是让你的Hound班级成为一个EventEmitter对象。

它为类提供了EventEmitter 实例方法

例如,houndInstance.emit('something')

正在监听这些事件的其他对象然后可以响应它们。


根据您的评论:

// constructor
function Hound() {

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

在 JavaScript 中,.call(context)是一种在特定上下文中调用函数的方法。在上面的示例中,我们只是调用SomeClass构造函数并将thisHound本示例中的类)作为上下文传递。

于 2012-12-06T05:51:47.927 回答
1

从您的评论中:

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

您缺少的是util.inherits()仅继承父对象。它没有设置构造函数来自动调用父对象的构造函数。在大多数情况下,这已经足够了,因为大多数对象在它们的构造函数中并没有做太多的初始化。

events.EventEmitter显然在构造函数中进行了一些初始化,这些初始化具有一些重要的副作用。由于原型继承不会自动调用父类的构造函数,在这种情况下您需要手动调用它。因此这events.EventEmitter.call(this)条线。


请注意,另一种方法是使用总是调用父构造函数的模块模式。这是因为模块模式本身不是继承,而是通过滥用 mixin/decorator 模式来模拟继承——它从父构造函数创建一个对象并手动为其添加属性。很多人不喜欢模块模式,因为它重复了函数和属性——因此他们认为它是在浪费内存。此外,这不是正确的继承,因此会破坏instanceof.

于 2012-12-06T07:08:07.450 回答