127

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.

Community
  • 1
  • 1
Tom Mesgert
  • 1,301
  • 2
  • 10
  • 6
  • http://stackoverflow.com/questions/921789/how-to-loop-through-javascript-object-literal-with-objects-as-members – Phil Cross Aug 07 '12 at 12:55
  • Are you using jQuery? What result do you expect? Three 'true' in console? – davids Aug 07 '12 at 12:56
  • jQuery's documentation of $.each (http://api.jquery.com/jQuery.each/) has a perfect example -- see 2nd code block on the page. Uses alert() instead of console.log(). – Faust Aug 07 '12 at 13:00

3 Answers3

326

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);
}); 

Another option would be to use vanilla Javascript using the Object.keys() and the Array .map() functions like this

Object.keys(object).map(function(objectKey, index) {
    var value = object[objectKey];
    console.log(value);
});

See https://developer.mozilla.org/nl/docs/Web/JavaScript/Reference/Global_Objects/Object/keys and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

These are usually better than using a vanilla Javascript for-loop, unless you really understand the implications of using a normal for-loop and see use for it's specific characteristics like looping over the property chain.

But usually, a for-loop doesn't work better than jQuery or Object.keys().map(). I'll go into two potential issues with using a plain for-loop below.


Right, so also pointed out in other answers, a plain Javascript alternative would be

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

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 and Object.keys functions take 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 ids button0, button1, button2 etc, and we want to set an onclick on them and do a console.log like this:

<button id='button0'>click</button>
<button id='button1'>click</button>
<button id='button2'>click</button>

var messagesByButtonId = {"button0" : "clicked first!", "button1" : "clicked middle!", "button2" : "clicked last!"];
for(var buttonId in messagesByButtonId ) { 
   if (messagesByButtonId.hasOwnProperty(buttonId)) {
       $('#'+buttonId).click(function() {
           var message = messagesByButtonId[buttonId];
           console.log(message);
       });
   }
}

If, after some time, we click any of the buttons we will always get "clicked last!" in the console, and never "clicked first!" or "clicked middle!". Why? Because at the time that the onclick function is executed, it will display messagesByButtonId[buttonId] using the buttonId variable at that moment. And since the loop has finished at that moment, the buttonId variable will still be "button2" (the value it had during the last loop iteration), and so messagesByButtonId[buttonId] will be messagesByButtonId["button2"], i.e. "clicked 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 and Object.keys().map() solve 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.

Willem Mulder
  • 12,974
  • 3
  • 37
  • 62
78
for(var key in object) {
   console.log(object[key]);
}
Saket Patel
  • 6,573
  • 1
  • 27
  • 36
  • thanks, but this return me "true", instead of aaa,bbb,ccc :( – Tom Mesgert Aug 07 '12 at 13:19
  • 3
    yeah thats what its priting to console the value of attributes which is true for every key, if you want to see aaa, bbb, ccc then use `console.log(key);` – Saket Patel Aug 07 '12 at 17:34
  • 14
    Note that you might want to check whether the found key comes from the object itself, or from up the prototype chain. Use object.hasOwnProperty(key) to check that – Willem Mulder Oct 03 '13 at 11:26
  • 1
    yes that's true, but adding property in object prototype is always a bad thing :) as that will affect all child object's like array, string etc – Saket Patel Oct 03 '13 at 13:23
  • Thank you. It works for my objectives. – LUISAO May 30 '21 at 22:32
  • Would NOT recommend. for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array. – Dennis Jan 20 '22 at 19:12
-1

var object = { "a": 1, "b": 2};
$.each(object, function(key, value){
  console.log(key + ": " + object[key]);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
//output
a: 1
b: 2
arhak
  • 2,488
  • 1
  • 24
  • 38
xiaowl
  • 5,177
  • 3
  • 27
  • 28