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