29
var myArr = [{a:1, b:2}, {c:3, d:4}];

for (var item in myArr) {
    console.log(item);
}

Item returns the key (ex: 0, 1) instead of the object itself. Why?

Andy Hin
  • 30,345
  • 42
  • 99
  • 142

4 Answers4

36

Douglas Crockford recommends in JavaScript: The Good Parts to avoid using the for in statement.

If you use for in to loop over property names in an object, the results are not ordered.

The for in loop is best for iterating over name-value pairs, and the for each loop best for iterating over values i.e arrays.

E.g,

var o = {'name':'Batman', 'age':33, 'city':'Gotham City'};
   for (var p in o) {
        console.log(p+': '+o[p]);
    }

There’s no way we can get the property name if we were to use the For Each Loop for the above object.


Note :

  1. The For in Loop is best for name-value pairs.
  2. The For Each Loop is best for iterable values. Eg: arrays, and objects if you are not interested in the name of the property.
Saurabh Gokhale
  • 53,625
  • 36
  • 139
  • 164
  • Thanks. I've been meaning to read that book. I had no idea of the existence of a 'for each' loop - is this supported by all major browsers? – Andy Hin Jul 03 '11 at 20:20
  • 3
    @Andy: The [`for each ... in`](https://developer.mozilla.org/en/JavaScript/Reference/Statements/for_each...in) statement is an extension only available in Mozilla based implementations, (it won't work on other browsers). When working with arrays, just use any sequential loop... [See also](http://stackoverflow.com/questions/500504/javascript-for-in-with-arrays/4261096#4261096). – Christian C. Salvadó Jul 03 '11 at 20:35
  • 1
    It's worth noting that *for..in* is useful for sparse arrays provided inhertied enumerable properties are dealt with (e.g. a *hasOwnProperty* test) and order is not important. – RobG Jul 04 '11 at 00:33
  • 2
    This shouldn't be marked as the answer as it works for simple arrays, not arrays of objects – Luke Pring Apr 10 '16 at 10:37
  • 1
    This answer is outdated. The new and vastly improved way to achieve this (with ECMAScript 6) is with a `for...of` loop. See the answer below. – GrayedFox Aug 02 '16 at 16:18
22

Javascript for..in loops always return the index/name, not the value. To get what you want, you should use:

var myArr = [{a:1, b:2}, {c:3, d:4}];

for (var index in myArr) {
    console.log( myArr[index] );
}

However, as said before, the for..in statement should be use with caution, and it is not intended to be used with an array. You should use a for loop instead

var myArr = [{a:1, b:2}, {c:3, d:4}];

for( var i=0, l=myArr.length; i<l; i++ ) {
    console.log( myArr[i] );
}
RyanZim
  • 6,609
  • 1
  • 27
  • 43
pomeh
  • 4,742
  • 4
  • 23
  • 44
3

The for ... in loop iterates over the keys (properties) of an object.
It is not intended to be used for arrays.

It will also iterate over properties inherited from the object's prototype.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 1
    But it is not a hashmap/key-value pair. If I did a for...in loop with ['a','b','c'] or [1,2,3] it would return the value and not the index. EDIT: just saw your update. I'll just iterate using a regular for loop then. Thanks! – Andy Hin Jul 03 '11 at 20:15
  • 4
    @andy: Wrong; it will return the index. Arrays are just objects that have numeric keys and a special `length` property. – SLaks Jul 03 '11 at 20:17
1

Adding an answer here to accommodate the latest ECMAScript 6 standard.

Check out this page for a great read with examples.

And a rather tasty caveat: this awesome new functionality will work with nearly ever iterable object! From MDN:

The for...of statement creates a loop iterating over iterable objects (including Array, Map, Set, String, TypedArray, arguments object and so on)...

So for example, you could use:

for (let item of myArr) {
    console.log(item);
} 

Although to super clear that you are logging an object, I would be a bit nicer to the next person to read your code by renaming "item" to "obj", producing this:

for (let obj of myArr) {
    console.log(obj);
} 

Why rename the variable? Well, although we use the term 'item' to denote any generic item in an array, your array only contains objects. If you know, or expect, this array to only every contain objects, you could name the variable based on the type of item (i.e. an object) the array contains.

Happy coding!

GrayedFox
  • 2,350
  • 26
  • 44