Javascript: cacher les méthodes prototypes dans la boucle?

Donc disons que j'ai ajouté des méthodes prototypes à la classe Array:

Array.prototype.containsKey = function(obj) { for(var key in this) if (key == obj) return true; return false; } Array.prototype.containsValue = function(obj) { for(var key in this) if (this[key] == obj) return true; return false; } 

Puis je crée un tableau associatif et j'essaie de bouger ses clés:

 var arr = new Array(); arr['One'] = 1; arr['Two'] = 2; arr['Three'] = 3; for(var key in arr) alert(key); 

Cela renvoie cinq éléments:

   -Un
   -Deux
   -Trois
   -contient la clé
   -containsValue

Mais je veux (attendez-vous) seulement trois. Est-ce que je suis proche de ce problème? Existe-t-il un moyen de "cacher" les méthodes prototypes? Ou devrais-je faire quelque chose de différent?

Vous pouvez utiliser la méthode hasOwnProperty de JavaScript pour l'atteindre en boucle, comme ceci:

 for(var key in arr) { if (arr.hasOwnProperty(key)) { ... } } 

Référence: Cet article de blog YUI .

Vous pouvez obtenir le résultat souhaité de l'autre extrémité en faisant en sorte que les méthodes prototypes ne soient pas énumérées:

 Object.defineProperty(Array.prototype, "containsKey", { enumerable: false, value: function(obj) { for(var key in this) if (key == obj) return true; return false; } }); 

Cela fonctionne généralement mieux si vous avez un contrôle sur les définitions de la méthode et, en particulier, si vous ne maîtrisez pas la façon dont votre code sera appelé par d'autres personnes, ce qui est une hypothèse commune dans le développement du code de la bibliothèque.

Javascript ne prend pas en charge les tableaux associatifs comme vous le pensez. http://ajaxian.com/archives/javascript-associative-arrays-considered-harmful

Pour (var i in .. obtient toutes les propriétés d'un objet (un tableau est juste un autre objet), c'est pourquoi vous voyez les autres objets que vous avez prototypés.

Comme l'article suggère, vous devez utiliser un objet:

 var assoc = {'One' : 1, 'Two' : 2}; assoc['Three'] = 3; for(var key in assoc) alert(key+' => '+assoc[key]); 

Vous pourriez faire ceci:

 for(var key in arr) { if (typeof(arr[key]) == "function") continue; alert(key); } 

Mais c'est une mauvaise solution de rechange

Pour l'itération haute performance sur les tableaux JavaScript, utilisez une boucle for ou while. Nicholas Zakas discute des options les plus performantes pour itérer sur les tableaux dans son Tech Talk Speed ​​Up Your JavaScript .

Votre meilleur pari est probablement quelque chose comme ceci:

 for (var i = collection.length - 1; i >= 0; i--) { if (obj == collection[i]) return true; } 

Cette approche sera préférable pour quelques raisons:

  • Seule une seule variable locale est attribuée
  • La propriété de length de collection n'est accessible qu'une fois, lors de l'initialisation de la boucle
  • Chaque itération, un local est comparé à une constante ( i >= 0 ) au lieu d'une autre variable