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

Hel*_*rld 72 javascript asynchronous

我目前正在阅读Trevor Burnham的Async Javascript.到目前为止,这是一本很棒的书.

他谈到这个片段和console.log在Safari和Chrome控制台中是"异步"的.不幸的是我不能复制这个.这是代码:

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

如果这是异步,我会预期结果将成为书籍的结果.console.log()被放入事件队列中,直到执行完所有代码,然后运行它并具有bar属性.

虽然它正在同步运行但它似乎出现了.

我运行此代码错了吗?console.log实际上是异步吗?

Ber*_*rgi 95

console.log没有标准化,因此行为相当未定义,并且可以从开发工具的发布版本轻松更改.你的书很可能已经过时了,我的答案很快就会出现.

对于我们的代码,无论是否console.log异步都没有任何区别,它不提供任何类型的回调左右; 并且在调用函数时始终引用和计算传递的值.

我们真的不知道接下来会发生什么(好吧,我们可以,因为Firebug,Chrome Devtools和Opera Dragonfly都是开源的).控制台需要将记录的值存储在某个位置,它将在屏幕上显示它们.渲染将异步发生(被限制为速率限制更新),未来与控制台中已记录对象的交互(如扩展对象属性)也是如此.

因此,控制台可能克隆(序列化)您记录的可变对象,或者它将存储对它们的引用.第一个不适合深层物体.此外,至少控制台中的初始渲染可能会显示对象的"当前"状态,即记录时的状态 - 在您看到的示例中Object {}.

但是,当您展开对象以进一步检查其属性时,控制台可能只存储了对象及其属性的引用,现在显示它们将显示它们当前(已经变异)的状态.如果单击,则+应该能够bar在示例中看到该属性.

这是在错误报告中发布的截图,用于解释他们的"修复":

因此,某些值可能在记录后很长时间被引用,并且对这些值的评估相当懒惰("需要时").这个差异最着名的例子是在Chrome的JavaScript控制台是否懒于评估数组的问题中处理的解决方法是确保始终记录对象的序列化快照,例如通过执行操作console.log(JSON.stringify(obj)).但这仅适用于非圆形和相当小的物体.另请参见如何更改console.log的默认行为?(*Safari中的错误控制台,没有加载项*).

  • 如果您使用`JSON.parse(JSON.stringify(obj))`,正如评论中提到的[此处](/sf/ask/1640044241/# comment73625080_23429304)您会得到对象形式的快照,而不是字符串。 (4认同)
  • 我在console.log没有同步时遇到了同样的问题。使用JSON.stringify为我修复了它 (2认同)