I have an associative array with two object inside. Running this through $(myassoc).each()
, the callback runs only once. Also the callback parameters (index and object) returns 0 and the entire associative array, respectively.
One would expect jQuery.each()
to run for each element in the array, returning the correct keys as index and the correct element as the object.
Why isn't that happening, and can jQuery do what I'm after?
The problem is that the
$.each()
function internally retrieves and uses thelength
property of the passed collection. But in an associative array that has no integer indices thelength
always seems to be0
. For$.each()
now there seems to be nothing to walk through.The solutions is simply to use an object instead.
Badly.
Don't
$(associative_array).each(function () {...})
-- that's nonsenseDon't
$.each(associative_array, function() {...});
-- that has an obscure bug(1)To see the bug, try this in a javascript console:
The first example outputs three lines of key-value pairs, as it should. The second outputs nothing!
The moral of the story, don't use jQuery.each() on objects. (Objects in JavaScript are essentially the same thing as associative arrays.) Things may work fine forever, but you run the risk that someday an object happens to have a member named
length
and its value happens to be exactly0
and then you have a bug out of nowhere that can be very difficult to explain. (I'll let you guess, by the ponderous heft of this answer, whether that ever happened to me.)As mentioned in the bug report:
I suggest going further, that jQuery.each should not be relied upon for associative arrays, ever.
(1) This "bug" may never be fixed, since $.each() historically uses Duck Typing on arrays: "Arrays and array-like objects with a length property (such as a function's arguments object) are iterated by numeric index."
Here's what I use[thanks Dominik] to loop through property names and values of objects, or put another way, the keys and values of an associative array:
looper() is then a drop-in replacement for $.each()
Just like $.each():
this
is each valuefalse
(not just falsy) terminates the loopUse:
Try that with $.each() and you'll get an empty result. Because it interprets this particular object as an array-like object of zero length.
try this:
I think you're looking for jQuery.each() instead of .each()
try this: