conclusion

For the “asynchronous phenomenon” of printing results and executing code in inconsistent order in the browser console. There are mainly two kinds of opinions on the Internet. The author prefers the first one here, which is easy to understand and conforms to the author’s test

  • Browsers, for optimization purposes, do not expand all objects by default, but only “read the corresponding value” when manually clicking to expand. A “click” is an action after code execution is complete, so printing a deep object is always a snapshot of the last moment.
  • Different browsers may have their own console.log implementation mechanism, limited by the fact that I/O performance may not match the time of printing and the time of code execution. That is to say, if the printing time is later, the printing result will be consistent before and after the change because the referenced data has been modified during printing

The body of the

Console. log is one of the more common debugging techniques used in daily development. We all know he can print messages to the console. Consider the following example

			const a=[{name:0}];
			console.log(a);
			a[0].name++;
			console.log(a);
Copy the code

In our opinion, it should be printed successively

			// [{name:0}]
			// [{name:1}] 
Copy the code

However, after the actual experiment of the author, “Google Browser version 93.0.4577.82 (official version) (x86_64)”. There’s a big difference between what it actually prints and what it feels like. It actually prints

			// [{name:1}]
			// [{name:1}] 
Copy the code

From this result, it looks like console.log is an asynchronous method, and printing is done after the code has been executed. Scroll through “JavaScript you Didn’t know.

There is no specification or set of requirements that specify how the console.* family of methods should work — they are not a formal part of JavaScript, but are added to it by the host environment (see the “Types and Syntax” section of this book). Therefore, different browsers and JavaScript environments can be implemented as they wish, which can sometimes lead to confusion. In particular, under certain conditions, the console.log(..) of some browsers Incoming content is not output immediately. The main reason for this is that IN many programs (not just JavaScript), I/O is a very slow blocking part. So, (from a page /UI perspective) the browser can improve performance by asynchronously processing console I/O in the background, where the user may not even be aware of it happening.

Okay, that’s a big headache. But the general idea is that different browsers may have their own console.log implementation mechanism, limited by the I/O performance that may not match the timing of printing and code execution. That is to say, if the printing time is later, the printing result will be consistent before and after the change because the referenced data has been modified during printing. That kind of makes sense. Let’s look at the next example:

                        const c={age:0}
                        console.log(c);
                        c.age++
                        console.log(c);
                        // The sequence of prints is
                        //{age: 0}
                        //{age: 1}
Copy the code

Seeing this is true, bengbu is living in Bengbu. Why can this example accord with our logical cognition? Run the sample code to see the following figure


                    const a=[{name:0}]
                    console.log(a,'Initial: 0 pre-a to expand');
                    a[0].name++
                    console.log(a,'Initial: 0 after-a to expand');
                    const b={info: {age:0}}
                    console.log(b,'Initial: 0 pre-b to expand');
                    b.info.age++
                    console.log(b,'Initial: 0 after-b to expand');
                    const c={age:0}
                    console.log(c,'Initial: 0 pre-C does not need to expand');
                    c.age++
                    console.log(c,'initial: 0 after-c unexpanded');
Copy the code

What do they have in common? As you can see from the figure, browser controls for objects and arrays only expand the first layer by default, and deeper objects use “…” Said. So here’s another way to say it: browsers don’t expand all objects by default for optimization purposes, and only “read the corresponding value” when they manually click to expand. So all of the examples above make sense from this perspective.

The resources

  • You don’t know JavaScript volumes
  • Juejin. Cn/post / 695610…