2011-09-28 4 views
3

Ignorant le fait que cela est mis en œuvre par nombreux cadres ..Qu'est-ce qu'une meilleure approche de prototype pour plusieurs types

Quelle est la meilleure façon de prototype pour plusieurs types d'objets.

Par exemple, devrais-je écrire:

Element.prototype.bind = function(eventType, fn) { 
    this.addEventListener(eventType, fn, false); 
}; 
NodeList.prototype.bind = function(eventType, fn) { 
    for (var i = 0, l = this.length; i < l; i++) { 
     this[i].addEventListener(eventType, fn, false); 
    } 
}; 

ou

Object.prototype.bind = function(eventType, fn) { 
    if (this instanceof Element) { 
     this.addEventListener(eventType, fn, false); 
    } else if (this instanceof NodeList) { 
     for (var i = 0, l = this.length; i < l; i++) { 
      this[i].addEventListener(eventType, fn, false); 
     } 
    } 
} 
+1

http://jsperf.com/prototype-methods Ok, donc j'ai trouvé que la première méthode est une meilleure performance, et je suppose qu'il offre aussi moins de chances de conflits ? – rlemon

+0

Ouais c'est aussi plus propre et plus facile à lire à mon humble avis ... si vous voulez la même fonction sur plusieurs types alors le code est beaucoup plus propre. Imagine 'cette instance d'Element || cette instance de OtherType || ... ': O –

+0

Le meilleur endroit pour cela est probablement SO. Pourriez-vous ajouter un peu de contexte? Quels problèmes avez-vous rencontrés qui vous ont amené à demander cela? –

Répondre

3

Big drapeau rouge: jamais étendre Object.prototype! Il casse for (x in y) (ou au moins les attentes des gens de la façon dont cela fonctionne).

Dans le cas général, cependant, il est préférable d'étendre les prototypes de types individuels plutôt que d'essayer de trouver une base commune et d'effectuer des vérifications de réflexion. Il y a deux raisons fondamentales à cela. Tout d'abord, JavaScript est un langage dynamiquement typé, donc vous devriez généralement préférer le typage de canard et l'héritage de base sur instanceof et la réflexion. Dans de nombreux cas, il y a un petit avantage de performance, mais surtout c'est pour que vous ne perdiez pas de temps à combattre la langue. Deuxièmement, ce type de changement de méthode implique des connexions entre les méthodes commutées qui n'existent pas nécessairement. Dans votre exemple de code, cela peut être vu dans la version NodeList. Conceptuellement, une liste ne devrait pas être contraignante; s'il a une méthode bind, il devrait simplement traduire en appelant la méthode bind sur chacun de ses éléments. Cela garantit que si des étapes supplémentaires doivent être ajoutées à la liaison dans le futur (par exemple, solutions de contournement pour les anciens navigateurs non conformes au DOM ...), vous n'avez besoin de le faire qu'au même endroit. Mais le regarder en termes de commutation de type dans la "même fonction" donne la fausse impression que les deux Element.bind et NodeList.bind devraient fonctionner de la même manière - en appelant addEventListener. Voici comment je le mettre en œuvre:

Element.prototype.bind = function(eventType, fn) { 
    this.addEventListener(eventType, fn, false); 
}; 

NodeList.prototype.bind = function(eventType, fn) { 
    for (var i = 0, l = this.length; i < l; i++) { 
     this[i].bind(eventType, fn); 
    } 
}; 
+1

Merci, vous êtes la première personne à tenter cela sans être accroché au fait que j'étendais 'Object.prototype'. Je vais commencer par * Je comprends les implications de faire cela, mais j'apprécie l'avertissement *. Tout le reste dans votre réponse est exactement l'information que je cherchais. – rlemon

Questions connexes