yxfxmx
yxfxmx

Reputation: 725

Copying object properties to array with an empty body for-in loop

`I'm reading 'JavaScript: the definitive guide' and I'm getting hung up on an example:

“you can use code like the following to copy the names of all object properties into an array"

var o = {x:1, y:2, z:3};
var a = [], i = 0;
for(a[i++] in o) /* empty */;

I don't understand, why does the last line really do anything, without instructions. Why does it fill the array?

Upvotes: 5

Views: 190

Answers (3)

hugomg
hugomg

Reputation: 69934

Wow, I'm actually surprised that this code works! Let me just say that I wouldn't recommend using it and would expect this sort of a[i++] trickery to show up in ancient C, not in Javascript :)

As for why it works, it has to do with the syntax of the language. The syntax for a for Loop is:

for ( LeftHandSideExpression in Expression ) Statement

A LeftHandSideExpression is anything that you can assign to with the = operator. In a for loop, usually we just use a variable identifier as in for(k in o) but since arr[i] is also a valid LHS expression (you can do arr[i] =) we are also allowed to write for(arr[i] in o).

In the end, your loop does something similar to

var a=[], i=0;
a[i++] = "x";
a[i++] = "y";
a[i++] = "z";
// in the end, a should be ["x", "y", "z"]
// and i should be 3

Upvotes: 3

Collett89
Collett89

Reputation: 381

this works because the for loop assigns the values in o to the variable left of the in.

usually this would be a new variable for use in some function. e.g. for(var a in o){/* do something with a */}

In this case it assigns it to a[i++] where the i++ increases by 1 each time

it is also worth pointing out the importance of the ; in for(a[i++] in o) /* empty */; this closes each iteration of the for. Without it the next line/loop (whatever it may be) would be repeated.

Upvotes: 6

Bergi
Bergi

Reputation: 664307

That's how for in loops work. You can specify an arbitrary left-hand expression as the reference to assign the keys. Usually it's just a reference to a variable, but you can use a property expression such as a[i++] as well.

From the spec:

  1. Let lhsRef be the result of evaluating the LeftHandSideExpression (it may be evaluated repeatedly).
  2. Call PutValue(lhsRef, P).

Maybe the code is easier written as

for(a[i] in o) i++;

Upvotes: 1

Related Questions