在看Async JavaScript这本书时意外发现有个地方跟作者结果不相同,然后就在Stack Overflow得到了解释。
原问题:
https://stackoverflow.com/questions/23392111/console-log-async-or-sync
问题:
书上说在webkit内核下:
var obj = {};
console.log(obj);
obj.foo = 'bar';
// {foo:bar}
实际上:
var obj = {};
console.log(obj);
obj.foo = 'bar';
{}
"bar"
我们打开obj对象的折叠:
神奇的发现obj竟然不空!
再来个更加直接的例子:
chrome浏览器中:
node环境下:
热闹看够了,我们来说说这个问题,在node环境console是严格同步的,所以正常执行,但是在作者写书时webkit有个问题,后来webkit就打了一个补丁,结果就跟以前不一样了。
事情发生的原因
至于为啥chrome打开就变成的跟表面上不一样了
控制台将需要将记录的值存储在某处,并将其显示在屏幕上。渲染将会以异步方式发生(被限制到速率限制更新),以及将来与控制台中记录的对象的交互(如扩展对象属性)的交互。
因此,控制台可能会克隆(序列化)您记录的可变对象,也可能存储对它们的引用。第一个对深层物体不能很好地工作。此外,至少在控制台中的初始呈现可能会显示对象的“当前”状态,即当您记录的示例中的对象的状态Object {}。但是,当您扩展对象以进一步检查其属性时,控制台可能只存储对对象及其属性的引用,并且现在显示它们将显示其当前(已突变)状态。
就是引用的原因啦,也就是给console.log传的参数其实是存在某处的,当前的结果是复制的可变对象,但是存储下来的是对象的引用就发生了表面上和打开对象结果不一样的现象了。