J'ai utilisé JSLint sur un de mes fichiers JavaScript. Il a jeté l'erreur:
for( ind in evtListeners ) {
Problème à la ligne 41, caractère 9: le corps d'un for in doit être encapsulé dans une instruction if pour filtrer les propriétés indésirables du prototype.
Qu'est-ce que ça veut dire?
javascript
jslint
jrharshath
la source
la source
if (evtListeners.hasOwnProperty(ind))
pour limiter le traitement uniquement aux propriétés propres (non héritées). Pourtant, dans certains cas, vous voulez vraiment parcourir toutes les propriétés, y compris celles héritées. Dans ce cas, JSLint vous oblige à encapsuler le corps de la boucle dans une instruction if pour décider quelles propriétés vous voulez vraiment. Cela fonctionnera et rendra JSlint heureux:if (evtListeners[ind] !== undefined)
Réponses:
Tout d'abord, n'utilisez jamais de
for in
boucle pour énumérer un tableau. Jamais. Utilisez du bon vieuxfor(var i = 0; i<arr.length; i++)
.La raison derrière cela est la suivante: chaque objet en JavaScript a un champ spécial appelé
prototype
. Tout ce que vous ajoutez à ce champ sera accessible sur tous les objets de ce type. Supposons que vous vouliez que tous les tableaux aient une nouvelle fonction cool appeléefilter_0
qui filtrera les zéros.Il s'agit d'une méthode standard pour étendre des objets et ajouter de nouvelles méthodes. De nombreuses bibliothèques le font. Cependant, regardons comment
for in
fonctionne maintenant:Est-ce que tu vois? Il pense soudainement que filter_0 est un autre index de tableau. Bien sûr, ce n'est pas vraiment un index numérique, mais il
for in
énumère les champs d'objet, pas seulement les index numériques. Nous énumérons donc maintenant chaque index numérique etfilter_0
. Maisfilter_0
n'est pas un champ d'un objet tableau particulier, chaque objet tableau a maintenant cette propriété.Heureusement, tous les objets ont une
hasOwnProperty
méthode qui vérifie si ce champ appartient vraiment à l'objet lui-même ou s'il est simplement hérité de la chaîne prototype et appartient donc à tous les objets de ce type.Notez que bien que ce code fonctionne comme prévu pour les tableaux, vous ne devez jamais, jamais utiliser
for in
etfor each in
pour les tableaux. N'oubliez pasfor in
qu'énumère les champs d'un objet, pas les index de tableau ou les valeurs.la source
for in
pour parcourir les tableaux car le langage ne garantit pas l'ordre dans lequelfor in
sera énuméré sur un tableau. Ce n'est peut-être pas dans l'ordre numérique. De plus, si vous utilisez le `for (i = 0; i <array.length; i ++) construction de style, vous pouvez être sûr que vous n'itérer les index numériques dans l' ordre, et pas de propriétés alphanumériques.for-in
boucles (qui sont géniales, soit dit en passant), nous devrions leur expliquer comment ils fonctionnent (fait correctement dans cette réponse) et les leur présenterObject.defineProperty()
afin qu'ils puissent étendre leurs prototypes en toute sécurité sans rien casser. Incidemment, l'extension des prototypes d'objets natifs ne devrait pas se faire sansObject.defineProperty
.Douglas Crockford, l'auteur de jslint a écrit (et parlé) à ce sujet à plusieurs reprises. Il y a une section sur cette page de son site Web qui couvre ceci:
Crockford a également une série de vidéos sur le théâtre YUI où il en parle. La série de vidéos / discussions sur javascript de Crockford est un must si vous êtes même un peu sérieux au sujet de javascript.
la source
Mauvais: (jsHint générera une erreur)
Bien:
la source
La réponse de Vava est dans le mille. Si vous utilisez jQuery, la
$.each()
fonction s'en charge, il est donc plus sûr de l'utiliser.la source
$.each
(ou underscore.js_.each
) si vous pouvez vous en sortir avec lafor
boucle brute . jsperf a quelques tests de comparaison révélateurs qui valent la peine d'être exécutés.@all - tout en JavaScript est un objet (), donc les instructions comme "n'utiliser ceci que sur des objets" sont un peu trompeuses. De plus, JavaScript n'est pas fortement typé de sorte que 1 == "1" soit vrai (bien que 1 === "1" ne le soit pas, Crockford est très important à ce sujet). En ce qui concerne le concept progromatique de tableaux dans JS, le typage est important dans la définition.
@Brenton - Pas besoin d'être un dictateur terminologique; "tableau associatif", "dictionnaire", "hachage", "objet", ces concepts de programmation s'appliquent tous à une structure dans JS. Il s'agit de paires de valeurs de nom (clé, index), où la valeur peut être n'importe quel autre objet (les chaînes sont également des objets)
Donc,
new Array()
c'est la même chose que[]
new Object()
est à peu près similaire à{}
Crée une structure qui est un tableau avec la restriction que tous les index (aka clés) doivent être un nombre entier. Il permet également l'attribution automatique de nouveaux index via .push ()
Est en effet mieux géré via
for(initialization;condition;update){
Mais qu'en est-il:
Essaye ça:
Peut-être pas la meilleure utilisation d'un tableau, mais juste une illustration que les choses ne sont pas toujours claires.
Si vous connaissez vos clés, et certainement si ce ne sont pas des nombres entiers, votre seule option de structure de type tableau est l'objet.
la source
C'est sûrement un peu extrême de dire
?
Il convient de souligner la section de l'extrait de Douglas Crockford
Si vous avez besoin d'un tableau associatif (aka table de hachage / dictionnaire) où les clés sont nommées au lieu d'être indexées numériquement, vous devrez l'implémenter comme un objet, par exemple
var myAssocArray = {key1: "value1", key2: "value2"...};
.Dans ce cas, le résultat
myAssocArray.length
sera nul (car cet objet n'a pas de propriété 'length'), et vousi < myAssocArray.length
n'irez pas très loin. En plus de fournir une plus grande commodité, je m'attendrais à ce que les tableaux associatifs offrent des avantages de performances dans de nombreuses situations, car les clés de tableau peuvent être des propriétés utiles (c.-à-d. La propriété ou le nom d'ID d'un membre du tableau), ce qui signifie que vous n'avez pas à parcourir une longue tableau évaluant à plusieurs reprises si les instructions pour trouver l'entrée de tableau que vous recherchez.Quoi qu'il en soit, merci également pour l'explication des messages d'erreur JSLint, j'utiliserai maintenant la vérification «isOwnProperty» lors de l'interaction via ma myriade de tableaux associatifs!
la source
length
propriété, mais vous pouvez le faire d'une autre manière:var myArr = []; myArr['key1'] = 'hello'; myArr['key2'] = 'world';
var myArr = []
, il devrait êtrevar myArr = {}
en PHP, c'est la même chose, mais pas en JS.Cela signifie que vous devez filtrer les propriétés d'evtListeners avec la méthode hasOwnProperty .
la source
Juste pour ajouter au sujet de for in / for / $. Each, j'ai ajouté un cas de test jsperf pour utiliser $ .each vs for in: http://jsperf.com/each-vs-for-in/2
Différents navigateurs / versions le gèrent différemment, mais il semble que $ .each et directement pour soient les options les moins chères en termes de performances.
Si vous utilisez for in pour parcourir un tableau / objet associatif, sachant ce que vous recherchez et ignorant tout le reste, utilisez $ .each si vous utilisez jQuery, ou simplement for in (puis une pause; une fois que vous avez atteint ce que vous savez devrait être le dernier élément)
Si vous parcourez un tableau pour effectuer quelque chose avec chaque paire de clés, utilisez la méthode hasOwnProperty si vous N'utilisez PAS jQuery et utilisez $ .each si vous utilisez jQuery.
Utilisez toujours
for(i=0;i<o.length;i++)
si vous n'avez pas besoin d'un tableau associatif ... lol chrome a effectué 97% plus rapidement qu'un for in ou$.each
la source