The problem

Recently, when I was debugging a project, I printed some data with console.log() for the convenience of debugging, but the printed data did not match my expectations. I mistook it as a code error and spent a lot of energy trying to find the cause. It turns out that the problem is with console.log(). The wrong pay…

I made a small example to demonstrate this, as follows:

By executing the following code on the Chrome console, I expected to print a value of 1, 2, and 3; As a result, the printed a has a value of 3. Why is that? Is console.log() executed asynchronously?

let arr = [];
let obj = {a:1};
arr.push(obj);
console.log(arr);
obj.a=2;
console.log(arr);
let obj1 = obj;
obj1.a=3;
console.log(arr);
//[{"a":3}]
//[{"a":3}]
//[{"a":3}]
Copy the code

I tried the same code again in the Node environment and the output was:

[ { a: 1 } ]
[ { a: 2 } ]
[ { a: 3 } ]

Copy the code

I don’t know why…

Analysis of the

The first thing you can confirm is that console.log is synchronized. The reason for this is that:

WebKit’s console.log does not take a snapshot of the object immediately; instead, it stores a reference to the object and then takes a snapshot when the code returns to the event queue. — “JavaScript Asynchronous Programming”

That is, in The WebKit-powered Chrome browser, the console’s default reference type reads one layer of data, and when you click expand, it goes to the heap to read the property values and the next layer of data.

This performance-first consideration can sometimes give the illusion that console.log is asynchronous. It also shows that debugging using console.log is unreliable… (Lesson learned)

To solve

We can use json.stringify (object) to serialize the object into a string to force a “snapshot” :

let arr = []; 
let obj = {a:1}; 
arr.push(obj); 
console.log(JSON.stringify(arr)); 
obj.a=2; 
console.log(JSON.stringify(arr)); 
let obj1 = obj; 
obj1.a=3; 
console.log(JSON.stringify(arr));
//[{"a":1}]
//[{"a":2}]
//[{"a":3}]
Copy the code

It’s best to debug directly with the Debugger.

conclusion

  • The Chrome browser console.log() is synchronized;
  • Debugging code printing with console.log() is not trusted.
  • Use the debugger for debugging