1

Consider next code:

var rows = [];
for (var i = 0; i < 10; i++) {
    rows.push({num:i});
    console.log(rows);
}

Why do I see next console output:

[Object]
[Object, Object]
[Object, Object, Object]
[Object, Object, Object, Object]
[Object, Object, Object, Object, Object]
[Object, Object, Object, Object, Object, Object]
[Object, Object, Object, Object, Object, Object, Object]
etc ...

But when I unfold, for example, first object I see all 10 objects in array but at this time I put only first one? So each iteration I see all 10 objects in array

I use chrome developers tools but the same picture in firebug, so I guess my mistake but can't figure out what's happening

Victor
  • 5,073
  • 15
  • 68
  • 120
  • 3
    Quick answer: It's not your fault, it's how the console works. – Felix Kling Jan 20 '14 at 09:31
  • Felix Kling, I saw this answer but 1. In firebug I see the same picture 2. It works nice when I have an array of numbers (not objects) – Victor Jan 20 '14 at 09:33
  • Firebug has the same problem ([I wrote about this long time ago](http://felix-kling.de/blog/2011/08/18/inspecting-variables-in-javascript-consoles/)). *"It works nice when I have an array of numbers (not objects)"* In my version of Chrome it doesn't let me expand an array of numbers so that's not an equivalent scenario. – Felix Kling Jan 20 '14 at 09:36
  • 1
    How about console.log(JSON.stringify(rows)); – mplungjan Jan 20 '14 at 09:36

2 Answers2

2

The console has the reference to the array which is changed in each iteration of the loop. When you examine the array the console will show the current state of it, regardless of the state of the array at the time the actual console.log is run. This is why you will always see all 10 objects in the array when inspecting it in the console.

EasyPush
  • 756
  • 4
  • 13
0

If console.log was only storing an object reference, not a while copy of the object, that would explain why, when logging it, you see the object in its final state. BUT... we also see the object shown as if it had a length of 1, then 2, ..., and it works with numbers, not objects, so it definitively seems like a bug, where only a part of the object is copied.

you can fix it by doing yourself the copy of the array (with slice(0)) :

var rows = [];
for (var i = 0; i < 10; i++) {
    rows.push({num:i});
    console.log(rows.slice(0));
}

this will output step by step as you want.

Still beware, because even when using slice, objects within the array won't get copied :

var rows = [];
for (var i = 0; i < 10; i++) {
  rows.push({num:i});
  if (i==3) rows[1].num = 1000;
  console.log(rows.slice(0));
}

the console will report rows[1].num to be 1000 even for indexes 0,1,2.

So if you might also change array items prior to reading them in the console, copying is not enough, you have to go for a deep copy of the array.

GameAlchemist
  • 18,995
  • 7
  • 36
  • 59