console.log()asynchronous或同步?

我正在阅读Trevor Burnham的Async Javascript 。 迄今为止这是一本很好的书。

他在Safari和Chrome控制台中讨论这个片段和console.log是“asynchronous”。 不幸的是我不能复制这个。 这里是代码:

var obj = {}; console.log(obj); obj.foo = 'bar'; // my outcome: Object{}; 'bar'; // The book outcome: {foo:bar}; 

如果这是asynchronous的,我预计结果是书的结果。 console.log()被放入事件队列中,直到所有的代码被执行,然后它被运行,它将有bar属性。

它似乎虽然是同步运行。

我运行这个代码错了吗? 是console.log实际上是asynchronous?

console.log不是标准化的,所以行为是相当不确定的,并且可以从开发工具的发布到发布轻松地进行改变。 你的书很可能已经过时,我的答案很快就会出现。

对于我们的代码来说, console.log是不是asynchronous的,它不提供任何forms的callback, 并且您传递的值总是在您调用函数时引用和计算。

我们真的不知道会发生什么(好吧,我们可以,因为Firebug,Chrome Devtools和Opera Dragonfly都是开源的)。 控制台将需要在某处存储logging的值,并将显示在屏幕上。 渲染将确实asynchronous发生(被限制更新的速率限制),以及将来与控制台中logging的对象的交互(如展开对象属性)。

因此,控制台可能会克隆(序列化)您logging的可变对象,或者将存储对它们的引用。 第一个对深层物体不适用。 此外,至less在控制台中的初始渲染可能会显示对象的“当前”状态,也就是login时的状态 – 在你的例子中你会看到Object {}

但是,当您扩展对象以进一步检查其属性时,控制台可能只会存储对象及其属性的引用,并且现在显示它们将显示其当前(已经突变)的状态。 如果你点击+ ,你应该可以在你的例子中看到bar属性。

以下是在错误报告中发布的截图,以解释他们的“修复”:

所以,一些值可能在被logging后很长时间被引用,并且对这些值的评估是相当懒惰的 (“需要时”)。 这个差异的最着名的例子是在Chrome的JavaScript控制台懒惰评估数组的问题处理? 解决方法是确保始终logging对象的序列化快照,例如通过执行console.log(JSON.stringify(obj)) 。 但是,这只适用于非圆形的,而非小的物体。 另请参见如何更改console.log的默认行为? (*在Safari浏览器错误控制台,没有附加*) 。

使用console.log时:

 a = {}; aa=1;console.log(a);ab=function(){}; // without b a = {}; aa=1;a.a1=1;a.a2=1;a.a3=1;a.a4=1;a.a5=1;a.a6=1;a.a7=1;a.a8=1;console.log(a);ab=function(){}; // with b, maybe a = {}; aa=function(){};console.log(a);ab=function(){}; // with b 

在第一种情况下,对象是很简单的,所以控制台可以“串”,然后呈现给你; 但在其他情况下,a太复杂了,不能“串化”,所以控制台会向你展示内存对象,而且当你看着它时,b已经被连接到a了。