views:

69

answers:

2

Given the following code:

var tmp = [0];
for(var i=0;i<100;i++) {
  tmp[0] = i;
  console.log(tmp);
}

I'd expect output of [0], [1], [2], [3], etc

But I instead get [99], [99], [99], [99], etc

Stepping through the code in a debugger (firebug) however nets me the correct result of [0], [1], [2].

+6  A: 
console.log(tmp[0])

When you put console.log(tmp) you are logging the entire array object. Firebug only creates a link to the object and then when you "look" at the object in firebug you are looking at its current state (after the for loop has completed).

Joshua
That seems awfully misleading (the way the console.log works). When I step through the code, why does it behave differently?
shasderias
@user414722: because when you step through, the evaluation is done each time a "step" completes. As for misleading... It's a feature: you're not logging text, you're logging an object reference, and they're all references to the same object. If you want a quick snapshot of the array, pass `tmp.slice()` to .log(); if you want a textual snapshot, just pass `tmp.toString()` to .log()
Shog9
So say console.log actually did some work, the correct way of writing the for loop would be to tmp.slice(); to pass in the "snapshot" of the array?
shasderias
@shasderias: what's "correct" depends entirely on what you want to happen. `console.log()` stores the reference for later use; if you want different references, you have to create them. If you're calling a routine that processes its inputs immediately rather than storing them, then you can get away with re-using the same object. I'm just explaining why the example you posted behaves the way it does... Since I don't know what you're actually trying to accomplish, I can't say how you should try to accomplish it.
Shog9
Got it, thank you very much. The actual problem is that I'm trying to pass the value to emit in a CouchDB map function, and truth to be told, I have no idea if it processes the input immediately. :PBut given my problem, I'm guessing that it doesn't, and thus .slice() would be correct.Thank you very much!
shasderias
A: 

That is interesting. Even without a for loop:

var tmp = [], i = 0;
tmp[0] = i;
console.log(tmp);
i++;
tmp[0] = i;
console.log(tmp);

produces

[1]
[1]

...as well. I was not aware that console.log behaved that way. Thanks to @Joshua for a good explanation.

cnanney