2012-12-06 5 views
1

J'ai été piquer dans certains modules Node.js dans l'espoir d'apprendre quelque chose que je pourrais avoir manqué lors de la création d'un module avec des fonctionnalités similaires. Puis je suis tombé sur ce code de Hound:Héritage bizarre dans Node.js

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

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

Je sais que la fonction util.inherits() de Node.js crée une nouvelle instance de Parent comme le prototype du constructeur de l'enfant as stated in the docs:

Le prototype du constructeur sera défini sur un nouvel objet créé à partir de superConstructor.

Donc, si notre constructeur hérite EventEmitter par util.inherits(), ce qui est que le code dans le constructeur pour?

+0

ressemble à un mauvais code pour moi –

+0

J'ai déjà vu ce genre de choses de temps en temps. J'ai toujours supposé qu'il était nécessaire d'appeler le super constructeur explicitement sur l'instance en cours de construction. Étant donné cet extrait des docs, je ne sais pas si c'est nécessaire ou non. Peut-être est-ce une vieille convention qui a été abandonnée quand «hériter» a fonctionné différemment? – chesles

+0

ce n'est pas un mauvais code; JavaScript n'a pas toutes les subtilités d'héritage des autres langues. C'est simplement comment node.js s'attend à ce que vous travailliez avec la classe EventEmitter. –

Répondre

1

Il s'agit simplement de faire de votre classe Hound un objet EventEmitter. Il donne le EventEmitter instance methods à la classe.

Par ex, houndInstance.emit('something')

D'autres objets qui écoutent ces événements peuvent alors y répondre.


par votre commentaire:

// constructor 
function Hound() { 

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

En JavaScript, .call(context) est un moyen d'invoquer une fonction dans un contexte spécifique. Dans l'exemple ci-dessus, nous appelons simplement le constructeur SomeClass et transmettons this (la classe Hound dans cet exemple) comme contexte.

+0

Mais util.inherits() 'ne couvre-t-il pas déjà cela? Ou est-ce que je manque quelque chose? – Joseph

+0

S'il vous plaît voir mon edit –

1

De vos commentaires:

Mais ne pas util.inherits() couvrent déjà? Ou est-ce que je manque quelque chose?

Ce qui vous manque, c'est que util.inherits() hérite simplement de l'objet parent. Il ne configure pas le constructeur pour appeler automatiquement le constructeur de l'objet parent. Dans la plupart des cas, cela suffirait car la plupart des objets ne font pas beaucoup d'initialisation dans leurs constructeurs.

Mais events.EventEmitter fait apparemment une certaine initialisation dans le constructeur qui a des effets secondaires importants. Comme l'héritage prototypique n'appelle pas automatiquement le constructeur du parent, vous devez l'appeler manuellement dans ce cas. D'où la ligne events.EventEmitter.call(this).


Notez qu'une alternative est d'utiliser le modèle de module qui appelle toujours le constructeur du parent. En effet, le modèle de module n'est pas hérité en soi, mais émule l'héritage en abusant du modèle mixin/decorator - il crée un objet à partir du constructeur parent et y ajoute manuellement des attributs. Beaucoup de gens n'aiment pas le modèle de module parce qu'il duplique les fonctions et les attrubuts - d'où ils le voient comme un gaspillage de mémoire. En outre, ce n'est pas l'héritage approprié et ainsi casse des choses comme instanceof.