Ryan Shang

生死看淡,不服就干

0%

console.log()是同步还是异步?

​ 最近在研究对象深拷贝的时候无意间发现了这样一个现象:

1
2
3
4
let obj = {name: 'Ryan',info:{name:'Ryan'}};
console.log(obj);
obj.info.name = 'Shang';
console.log(obj);

​ 在html中写上这段代码,在chrome浏览器中执行的结果是这样:

![chrome console结果](2017-01-01-console.log是同步还是异步/chrome console结果.png)

​ obj.info.name的值竟然在第一次打印的时候就变了?难不成console.log是一个异步操作?

​ 接着我在node环境中试验了一下:

![node console结果](2017-01-01-console.log是同步还是异步/node console结果.png)

​ 结果正常。

​ 继续测试,我更改了下代码:

1
2
3
4
let obj = {name: 'Ryan',info:{name:'Ryan'}};
console.log(JSON.stringify(obj));
obj.info.name = 'Shang';
console.log(JSON.stringify(obj));

​ 结果是这样:

![chrome stringify结果](2017-01-01-console.log是同步还是异步/chrome stringify结果.png)

​ 这样更疑惑了。

​ 代码在node环境中运行和在字符串化后都正常。那么可能就是Chrome控制台的一个bug?

​ 在Google上搜寻了相关内容,结果比较有意思。

​ Chrome的控制台在处理对象时,有可能保存的是对象的引用地址。控制台对于引用地址的对象属性变化的更新可能是比较懒的,可能当你需要使用这个对象或对其进行操作时,它才会更新。所以,当你直接打印对象时,显示的是最近的状态,但你对obj进行操作后,显示的值就会更新为正确的值。

​ 大概就是这个原因导致文中的情况,不过究竟如何,还需要深入研究,可能我现在的思考结果也不一定对。

参考资料:

https://stackoverflow.com/questions/23392111/console-log-async-or-sync

https://stackoverflow.com/questions/4057440/is-chromes-javascript-console-lazy-about-evaluating-arrays