8

I'm somehow confused:

I have a list of commands like this:

var commands = [{"command": "read"}, {"command": "write"}, {"command": "login"}];

If I try it access one of the commands like this it works:

console.log(commands[0]["command"]); // Output is "read"
console.log(commands[0].command);    // Output is "read"

But if I try this the output is always undefined:

for(command in commands)
    console.log(command["command"]); // undefined, undefined, undefined
Lenar Hoyt
  • 5,971
  • 6
  • 49
  • 59
  • If your commands variable is json, you could also do this http://jsfiddle.net/aMTTU/ – Tim B James Aug 25 '11 at 12:42
  • 3
    In spite of some of the answers below, don't `for-in` an Array. It's the wrong tool for the job in JavaScript. A `for` loop or the `forEach` method ensures only numeric indices in a guaranteed order and doesn't block your ability to extend `Array.prototype` if you choose. – user113716 Aug 25 '11 at 12:54

6 Answers6

9

for does an array iteration in javascript, so you want:

for(command in commands)
    console.log(commands[command]["command"]);

ie, the command variable in your example is an array index, not the enumerated item from the array.

Jamiec
  • 133,658
  • 13
  • 134
  • 193
9

The for ... in construct iterates over the keys of the objects in the array, not the objects themselves. So you would need to write:

for(index in commands)
    console.log(commands[index]["command"]);
Jon
  • 428,835
  • 81
  • 738
  • 806
3

The for (.. in ..) construct is for looping over objects, not arrays. Since you have an array of objects, you should be doing:

for (var i = 0, j = commands.length; i < j; i += 1) {
  console.log(commands[i].command);
}

For a thorough explanation as to why you should use this for construct instead of the for...in, see answer #3010848.

Community
  • 1
  • 1
James Sumners
  • 14,485
  • 10
  • 59
  • 77
  • 1
    Uh, no, he has clearly defined an array of objects that he wishes to iterate: `var commands = [{"command": "read"}, {"command": "write"}, {"command": "login"}];` – James Sumners Aug 25 '11 at 12:44
  • 1
    @Martin Actually OP is creating an array of objects. The array is what is being looped through which is more natural as a `for` loop. – Adam Jones Aug 25 '11 at 12:45
2

Use it like this

 for(var x in commands)
      console.log(commands[x].command);
m0sa
  • 10,712
  • 4
  • 44
  • 91
2

Why use for..in with an array? Just access by index, and you also avoid potential problems of prototype extensions (see hasOwnProperty)

var i,len=commands.length;

for (i=0;i<len;i++ ) {
    console.log commands[i].command
}

If order does not matter, more concisely

for (i=commands.length-1;i>=0;i-- ) {

}

Or

var i=commands.length;
while (i--) {
   ...
}
Jamie Treworgy
  • 23,934
  • 8
  • 76
  • 119
1

Have you tried:

for(command in commands[0]) {
    console.log(command["command"]);
}
Seth
  • 6,240
  • 3
  • 28
  • 44
  • That won't work because `commands[0].command` is the `"read"` string, so `commands[0].command["command"]` will give you `undefined`. – user113716 Aug 25 '11 at 12:47