2

I'm confused about the difference between the output for the following two pieces of code:

var x = [{'size': 3}, {'size': 2}, {'size':1}];
console.log("Before I sort, x is", x);
x.sort(function(a, b) { 
    console.log("Sorting x…");
    return a.size - b.size; 
});
console.log("After I sort, x is", x);

yields

Printing the before-and-after of sorting an array.

…which is surprising since the "Before I sort…" array seems sorted. If I remove the sort, i.e. run

var x = [{'size': 3}, {'size': 2}, {'size':1}];
console.log("Before I sort, x is", x);
// x.sort(function(a, b) {  console.log("Sorting x…");
//  return a.size - b.size; });
// console.log("After I sort, x is", x);

Then I see what I expect in the first console.log, Printing only the before sorting of the array

Confused by this, I tried printing out x[0] as well, which is correct, even though the display of x is not, i.e.

var x = [{'size': 3}, {'size': 2}, {'size':1}];
console.log("Before I sort, x[0] is", x[0], "and x is", x);
x.sort(function(a, b) {  console.log("Sorting x…");
    return a.size - b.size; });
console.log("After I sort, x[0] is", x[0], "and x is", x);

yields

Printing the before and after of sorting the array, and the first element

…which seems inexplicable, since the printed x's are the same, even though x[0] is not.

What gives? How can I explain this behavior?

I hope it doesn't matter, but I'm running this on Google Chrome 69.0.3497.100 (Official Build) (64-bit)

Thanks!

aresnick
  • 1,635
  • 12
  • 24
  • 5
    It doesn't. Do this `console.log(JSON.parse(JSON.stringify(x)));` for the before and after logs. It's just the way the browser console works. It's logging the arrays by reference, not value, so by the time the log is actually shown to you, the array has been modified. – Reinstate Monica Cellio Oct 10 '18 at 13:19
  • 2
    The Chrome console is *notorious* for doing that sort of thing, and I'm sure countless legions of developers have wasted an insane amount of time being confused by the behavior. – Pointy Oct 10 '18 at 13:21
  • See ^^ that link for further discussion. – Reinstate Monica Cellio Oct 10 '18 at 13:21
  • 2
    It seems like this occurs because sort mutates the array, and it is kind of changed when you see it. If you try with some timeout, it prints array before it changes. `var x = [{'size': 3}, {'size': 2}, {'size':1}]; console.log("Before I sort, x is", x); setTimeout(() => { x.sort(function(a, b) { console.log("Sorting x…"); return a.size - b.size; }); console.log("After I sort, x is", x); }, 3000)` So it is better to not rely to console in such cases – Sergii Vorobei Oct 10 '18 at 13:21
  • 3
    Chrome dev tools attempts to warn you about this by showing you the little blue `i` icon – chazsolo Oct 10 '18 at 13:22
  • Oh great; thank you! That's very helpful— – aresnick Oct 10 '18 at 16:00

0 Answers0