3

I am getting unexpected console output after array assignment in webkit browsers (Chrome 16.0.912.77 and Safari 5.1.2 - 7534.52.7).

Here is my function that demonstrates the error:

function test() {
    var myArray = [];
    console.log(myArray); // Should be [], but is [0]
    myArray.push(0);
}

I receive the expected output of [] in Firefox 7.0.1.

[EDIT]

When I insert a long synchronous sleep, the problem doesn't go away. This makes me think that (1) even though the console.log statement is asynchronous, it is running in the same thread and (2) it is waiting until the event queue is empty before it runs and (3) the reference passed to console.log is being turned into a string when console.log is finally executed - not when it is called.

function sleep(millis){
  var date = new Date();
  var curDate = null;
  do { curDate = new Date(); }
  while(curDate-date < millis);
}

function test() {
    var myArray = [];
    console.log(myArray); // Should be [], but is [0]
    sleep(2000);    
    myArray.push(0);
}

This doesn't seem like desired behavior.

bbrame
  • 18,031
  • 10
  • 35
  • 52
  • Are you sure it's not just a naming thing, the fact that it's an array of size 0? Have you tried accessing myArray[0] in webkit browsers? – dougajmcdonald Jan 25 '12 at 15:14
  • 2
    possible duplicate of [Javascript Funky array mishap](http://stackoverflow.com/questions/8395718/javascript-funky-array-mishap) – Guffa Jan 25 '12 at 15:16
  • In regards to your edit, see the possible duplicate question. The results are evaluated on completion of the code. So no synchronous waiting. Use `.concat()` or `.join()` instead. – Ry- Jan 25 '12 at 15:45

1 Answers1

6

This is because console.log is by reference and asynchronous, and your push() ends up executing before the result is displayed.

You could do a quick:

console.log(myArray.slice());

Instead, for debugging purposes.


To test this more obviously:

var a = []; console.log(a); a.push(1, 2, 3, 4, 5);

will give [1, 2, 3, 4, 5].

var a = []; console.log(a); setTimeout(function() {a.push(1, 2, 3, 4, 5);}, t);

gives the wrong result for me with t = 5 and the right result for t = 100.

Ry-
  • 218,210
  • 55
  • 464
  • 476
  • Your explanation makes sense, but it doesn't seem like useful behavior. What use is console.log if you can't trust it's output (or must trust it very carefully)? Also, I get the same behavior when I insert a delay between the log statement and the push. – bbrame Jan 25 '12 at 15:19
  • 1
    @bbrame: It's not really intended to be used like that, I suppose; and as for the reason it's asynchronous, that's for performance. When you `console.log` an HTML element, it renders it as a tree. Log `jQuery('*')` and it would hang your JavaScript. – Ry- Jan 25 '12 at 15:22
  • 2
    @bbrame: No, it's not useful, and listed as bugs for the browsers that do this. Some browsers behave differently. – Guffa Jan 25 '12 at 15:23
  • @bbrame: `console.log` is so code can inconspicuously alert developers that there's an issue. It's no replacement for an interactive debugger when it comes time to fix the issue. – outis Jan 25 '12 at 22:15