2010-07-25 7 views
3

je le code suivantjQuery.each() question non définie

function myFunction(items) { 
    // this prints out 11 
    alert(items.length); 

    $(items).each(function(i, item) { 
     // item is undefined for some reason 
    } 
} 

J'alerter la longueur des articles, il a des éléments qu'il contient (11 pour être exact). Alors, comment 11 éléments peuvent-ils être présents, mais jQuery passe-t-il encore indéfini?

+4

Quelle est la valeur de '$ (this)' dans votre rappel '.each()'? Rien ne semble incorrect donc il serait utile de voir un [SSCCE] (http://sscce.org/). –

+0

Quel est le type de 'items'? est-ce un tableau ou un objet de type tableau comme un 'HTMLCollection' renvoyé par' .getElementsByClassName() 'par exemple. De toute façon, pourquoi ne pas simplement utiliser une norme pour la boucle? – jasongetsdown

Répondre

6

La seule explication à cela est le tableau que les éléments contient des valeurs qui ne sont pas définies, i.e.:

items = [undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined]; 

Les deux autres réponses sont totalement incorrectes. Le premier paramètre de each est l'index, pas la valeur, et jQuery.fn.each appelle jQuery.each. Il n'y a pas d'homonymie entre eux.

+0

Matt vous avez raison. C'est mon code qui a fait l'erreur. J'utilisais JSLINQ et j'ai écrit ma propre implémentation de Take (n). J'ajoutais des objets indéfinis à mon tableau par erreur à travers un bug de logique. –

+0

L'ancienne implémentation est Prendre: function (count) { var retVal = new Array(); pour (var index = 0; index

+0

Le nouveau est Prendre: function (count) { var retVal = new Array(); pour (var index = 0; index

5

Il semble que vous soyez pas en passant un jQuery wrappet set à votre fonction. Si vous passez un array ou un object vous devez utiliser le jQuery helper function.each $() comme

$.each(items, function(index, element){ 
}); 

Comme je l'ai déjà mentionné à plusieurs reprises dans d'autres réponses, il est une mauvaise pratique de boucle sur un tableau .each() ou javascripts natif for..in.

Si vous passez arrays, utilisez un for loop standard.

modifier

Comme il se trouve, vous fait vraiment pouvez appeler le jQuery constructor avec un tableau standard. Mais il semble que ce soit un karma terrible à faire, vous ne pouvez pas appeler 95% de toutes ces méthodes jQuery, à moins que vous ne vouliez planter/corrompre votre code.

+0

jAndy - Un tableau fonctionnera comme OP (bien que je sois d'accord que '$ .each()' soit meilleur et 'for loop' est le meilleur). – user113716

+0

@patrick: Doh je n'étais pas au courant de ça. Que se passe-t-il si vous passez un tableau standard au constructeur jQuery et que vous appelez '.animate()' ou quoi que ce soit dessus? – jAndy

+0

jAndy - Semble être un échec catastrophique (à moins bien sûr qu'il s'agisse d'un tableau d'éléments DOM). Une bonne raison de ne pas le faire.Mais là encore, quand on y pense, c'est ce que fait '.map()' de jQuery. Le rappel renvoie une valeur arbitraire, qui est placée dans un objet jQuery. – user113716

0

Depuis commentaires ne permettent pas des listes assez de code ... (-ils?):

Animer fonctionnera contre quoi que ce soit. Il est documenté que ne travaillant contre les propriétés CSS, mais juste pour prouver un point:

var foo = { x: 10, y: 12 }; 

$(foo).animate({ x: "+=20", y: "20" }, 1000, 
     function() { alert(foo.x + ":" + foo.y); }); 

va cracher « 30:20 ». Est-ce utile? Peut-être pas dans le travail quotidien. :)

L'astuce avec arrays est que vous définissez la même propriété pour chaque entrée. Exemple:

var foo = [{ x: 10 }, { x: 20 }]; 

$(foo).animate({ x: "+=30" }, 1000, 
     function() { alert(this.x); }); 

Éclate "40" et "50".