console.log
没有标准化,所以行为是相当未定义的,并且可以很容易地随开发人员工具的发布而改变。你的书可能已经过时了,我的回答也可能很快过时。
对于我们的代码,console.log
异步与否没有任何区别,它不提供任何类型的回调等;并且您传递的值始终在您调用函数时被引用和计算。
我们真的不知道会发生什么(好吧,我们可以,因为 Firebug、Chrome Devtools 和 Opera Dragonfly 都是开源的)。控制台需要将记录的值存储在某处,并将它们显示在屏幕上。渲染肯定会异步发生(受到速率限制更新的限制),未来与控制台中记录的对象的交互也会如此(例如扩展对象属性)。
因此,控制台可能会克隆(序列化)您记录的可变对象,或者存储对它们的引用。第一个不适用于深/大对象。此外,至少控制台中的初始渲染可能会显示对象的“当前”状态,即它被登录时的状态 - 在您的示例中您会看到Object {}
。
但是,当您展开对象以进一步检查其属性时,控制台可能只会存储对您的对象及其属性的引用,现在显示它们将显示它们当前(已发生变异)的状态。如果单击+
,您应该能够bar
在示例中看到该属性。
这是错误报告中发布的屏幕截图,用于解释他们的“修复”:
因此,某些值可能会在它们被记录后很久才被引用,并且对这些值的评估相当懒惰(“在需要时”)。这种差异最著名的例子是在问题Chrome 的 JavaScript 控制台是否懒惰评估数组中处理的?
一种解决方法是确保始终记录对象的序列化快照,例如通过执行console.log(JSON.stringify(obj))
. 不过,这仅适用于非圆形和相当小的物体。另请参阅如何更改 Safari 中 console.log 的默认行为?.
更好的解决方案是使用断点进行调试,在那里执行完全停止,您可以检查每个点的当前值。仅对可序列化和不可变数据使用日志记录。