Tom Mesgert Tom Mesgert - 5 months ago 22
jQuery Question

Each for object?


Possible Duplicate:

Iterate over Object Literal Values




I have object in JavaScript:

var object = someobject;

Object { aaa=true, bbb=true, ccc=true }


How can I use each for this?

object.each(function(index, value)) {
console.log(value);
}


Not working.

Answer

A javascript Object does not have a standard .each function. jQuery provides a function. See http://api.jquery.com/jQuery.each/ The below should work

$.each(object, function(index, value) {
    console.log(value);
}); 

I would suggest using this, as apposed to vanilla Javascript, unless you don't want to use jQuery at all or understand the implications of using a normal for-loop. I'll go into two potential issues with using a plain for-loop below.


Right, so also pointed out below, a plain Javascript alternative would be

for(var index in object) { 
    var attr = object[index]; 
}

As mentioned, there are two potential issues with this:

1 . You want to check whether the attribute that you are finding is from the object itself and not from up the prototype chain. This can be checked with the hasOwnProperty function like so

for(var index in object) { 
   if (object.hasOwnProperty(index)) {
       var attr = object[index];
   }
}

See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty for more information.

The jQuery.each function takes care of this automatically.

2 . Another potential issue with a plain for-loop is that of scope and non-closures. This is a bit complicated, but take for example the following code. We have a bunch of buttons with classes index0, index1, index2 etc, and we want to set an onclick on them and do a console.log like this:

<button class='index0'>click</button>
<button class='index1'>click</button>
<button class='index2'>click</button>

var object = ["first", "middle", "last"];
for(var index in object) { 
   if (object.hasOwnProperty(index)) {
       $('.index'+index).click(function() {
           console.log(object[index]);
       });
   }
}

If, after some time, we click any of the buttons we will always get "last" in the console, and never "first" or "middle". Why? Because at the time that the onclick function is executed, it will display object[index] using the index variable at that moment. And since the loop has finished at that moment, the index variable will still be "2" (the value it had during the last loop iteration), and so object[index] will be object[2], i.e. "last".

See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures for more information on closures. Especially the last part of that page that covers our example.

Again, jQuery.each solves this problem automatically for us, because it provides us with a function(index, value) (that has closure) so we are safe to use both index and value and rest assured that they have the value that we expect.