Ce qui ne l'JSLint erreur "corps de un pour dans doit être enveloppé dans une instruction if" signifie pour vous?
J'ai utilisé JSLint sur un fichier JavaScript de la mine. Il a jeté l'erreur:
for( ind in evtListeners ) {
Problème à la ligne 41 de caractère 9: Le corps d'un de doit être
enveloppé dans une instruction if pour filtrer les indésirables
propriétés du prototype.
Qu'est-ce que cela signifie?
- Par défaut 'dans' itère sur les propriétés héritées ainsi. Habituellement, le corps est enveloppé dans
if (evtListeners.hasOwnProperty(ind))
de limiter le traitement seulement propre (non héréditaire) propriétés. Encore, dans certains cas, vous voulez vraiment effectuer une itération sur toutes les propriétés, y compris celles héritées. Dans ce cas, JSLint vous oblige à envelopper le corps de la boucle dans une instruction if pour déterminer les propriétés que vous voulez vraiment. Cela permettra de travailler et de faire JSlint heureux:if (evtListeners[ind] !== undefined)
- La plupart des réponses sont obsolètes. une mise à jour de la solution peut être trouvé à l'adresse stackoverflow.com/a/10167931/3138375
Vous devez vous connecter pour publier un commentaire.
Tout d'abord, jamais utiliser un
for in
boucle pour énumérer sur un tableau. Jamais. Utiliser la bonne vieillefor(var i = 0; i<arr.length; i++)
.La raison derrière cela est le suivant: chaque objet en JavaScript a un champ spécial appelé
prototype
. Tout ce que vous ajoutez à ce champ va être accessible sur tous les objets de ce type. Supposons que vous voulez tous les tableaux d'avoir un cool nouvelle fonction appeléefilter_0
filtre remet à zéro.C'est un moyen d'étendre les objets et ajouter de nouvelles méthodes. Beaucoup de bibliothèques de le faire.
Cependant, regardons comment
for in
travaille maintenant:Voyez-vous? Soudain, elle pense filter_0 est un autre indice de tableau. Bien sûr, il n'est pas vraiment un indice numérique, mais
for in
énumère les champs objet, pas seulement des indices numériques. Nous sommes donc maintenant énumération dans tous les index numérique etfilter_0
. Maisfilter_0
n'est pas un champ d'un tableau d'objets, chaque objet array a 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 si elle est simplement hérité de la chaîne de prototype et appartient donc à tous les objets de ce type.Note que, même si ce code fonctionne comme prévu pour les tableaux, vous ne devriez jamais, jamais, utilisez
for in
etfor each in
pour les tableaux. Rappelez-vous quefor in
énumère les champs d'un objet, pas de tableau d'index ou de valeurs.for in
pour itérer sur tous les tableaux, parce que la langue n'est pas garauntee l'ordre dans lequelfor in
énumérer sur un tableau. Il pourrait ne pas être dans l'ordre numérique. En outre, si vous utilisez le `for(i=0;i<tableau.longueur;i++) style de construction, vous pouvez être sûr que vous êtes que itération indices numériques dans l'ordre, et non alphanumérique propriétés.for-in
boucles (qui sont géniaux, par la voie), nous devons les éduquer comment ils fonctionnent (fait correctement dans cette réponse) et de leur présenter leObject.defineProperty()
donc ils peuvent étendre leurs prototypes sans rien casser. Par ailleurs, l'extension des objets natifs des prototypes devraient pas se faire sansObject.defineProperty
.for(;;)
boucles, vous demandant d'utiliserfor...in
des boucles de la place. Ensuite vous met en garde pour ne pas utiliser si le filtre à l'intérieur de celui-ci...Douglas Crockford, l'auteur de jslint a (écrit et parlé) à propos de cette question de nombreuses fois. Il y a une section sur cette page de son site web qui couvre cette:
Crockford a également une série de vidéos sur YUI théâtre où il en parle. Crockford de la série de vidéos/discussions à propos de javascript sont un must si vous êtes même un peu de sérieux à propos de javascript.
Mauvais: (jsHint lèvera une erreur)
Bon:
Vava la réponse est sur la marque. Si vous utilisez jQuery, puis le
$.each()
fonction prend soin de cela, il est donc plus sûr à utiliser.$.each
(ou underscore.js's_.each
) si vous pouvez vous en sortir avec le rawfor
boucle. jsperf a un peu ouvert les yeux à des tests de comparaison qui valent la peine en cours d'exécution.@tous: tout est dans le JavaScript est un objet (), de sorte que des déclarations comme "seulement l'utiliser sur des objets" sont un peu trompeuses. En outre, le JavaScript n'est pas fortement typé, de sorte que 1 == "1" est vrai (bien que 1 === "1" n'est pas, Crockford est grande sur ce sujet). Quand il s'agit de la progromatic concept de tableaux en JS, la saisie est important dans la définition.
@Brenton - Pas besoin d'être une terminologie dictateur; "tableau associatif", "dictionnaire", "hash", "objet", ces concepts de la programmation s'appliquer à une structure en JS. C'est le nom (clé, l'indice de la valeur des paires, où la valeur peut être n'importe quel autre objet (chaînes de caractères sont des objets trop)
Donc,
new Array()
est le même que[]
new Object()
est à peu près similaire à{}
Crée une structure qui est un tableau avec la restriction que tous les index (aka touches) doit être un nombre entier. Il permet également à l'auto attribution de nouveaux indices via .push()
Est en effet préférable de traiter via
for(initialization;condition;update){
Mais qu':
Essayez ceci:
Peut-être pas la meilleure utilisation d'un tableau, mais juste une illustration de ce que les choses ne sont pas toujours évident.
Si vous connaissez vos clés, et certainement si elles ne sont pas des nombres entiers, votre seul tableau comme le choix de la structure est l'objet.
Sûrement, c'est un peu extrême de dire
?
Il convient de signaler l'article de Douglas Crockford extrait
Si vous avez besoin d'un tableau associatif ( alias de table de hachage /dictionnaire ) où les touches sont nommés à la place de la indexé numériquement, vous aurez à mettre en œuvre la présente comme un objet, par exemple
var myAssocArray = {key1: "value1", key2: "value2"...};
.Dans ce cas
myAssocArray.length
viendra null (parce que cet objet n'a pas une "longueur" de la propriété), et votrei < myAssocArray.length
vous n'obtiendrez pas très loin. En plus de fournir plus de commodité, je m'attends à des tableaux associatifs pour offrir des avantages en matière de performances dans de nombreuses situations, comme le tableau de clés peut être utile propriétés (c'est à dire un membre d'une pile est la propriété de l'ID ou le nom), ce qui signifie que vous n'avez pas à parcourir un long tableau à plusieurs reprises d'évaluer si les déclarations de trouver l'entrée de ce tableau que vous êtes après.De toute façon, merci aussi pour l'explication de la JSLint messages d'erreur, je vais utiliser le "isOwnProperty" vérifier maintenant quand interating par le biais de mon myriade de tableaux associatifs!
length
de la 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, ils sont la même chose, mais pas en JS.Cela signifie que vous devez filtrer les propriétés de evtListeners avec le hasOwnProperty méthode.
Juste à ajouter sur le sujet de en/pour/$.chacun, j'ai ajouté un jsperf de cas de test pour l'utilisation de $.chaque vs pour en: http://jsperf.com/each-vs-for-in/2
Différents navigateurs/versions gérer la situation différemment, mais il semble $.chaque et droite pour en sont les options les moins coûteuses en terme de performance.
Si vous êtes en utilisant pour en parcourir un tableau associatif/objet, sachant ce que vous êtes après, et en ignorant tout le reste, utiliser $.chaque si vous utilisez jQuery, ou tout simplement pour (et puis une pause; une fois que vous avez atteint ce que vous connaissez doit être le dernier élément)
Si vous êtes une itération à travers un tableau de réaliser quelque chose avec chaque paire de clés en, devraient utiliser le hasOwnProperty méthode si vous N'utilisez PAS de jQuery, et utiliser $.chaque si vous utilisez jQuery.
Toujours utiliser
for(i=0;i<o.length;i++)
si vous n'avez pas besoin d'un tableau associatif quoique... lol chrome effectué que 97% plus rapide qu'un pour dans ou$.each