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,722
  • 6
  • 46
  • 55
  • 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
  • 128,537
  • 12
  • 134
  • 188
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
  • 413,451
  • 75
  • 717
  • 787
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,055
  • 10
  • 57
  • 75
  • 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,342
  • 3
  • 41
  • 86
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,538
  • 8
  • 72
  • 117
1

Have you tried:

for(command in commands[0]) {
    console.log(command["command"]);
}
Seth
  • 6,180
  • 3
  • 27
  • 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