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

Javascript console.log()是异步还是同步?,javascript,asynchronous,Javascript,Asynchronous,我目前正在阅读特雷弗·伯纳姆的作品。到目前为止,这是一本很棒的书 他谈到这个代码段和console.log在Safari和Chrome控制台中是“异步”的。不幸的是,我不能复制这个。代码如下: var obj = {}; console.log(obj); obj.foo = 'bar'; // my outcome: Object{}; 'bar'; // The book outcome: {foo:bar}; 如果这是异步的,我会预期结果将是books的结果。将console.log

我目前正在阅读特雷弗·伯纳姆的作品。到目前为止,这是一本很棒的书

他谈到这个代码段和console.log在Safari和Chrome控制台中是“异步”的。不幸的是,我不能复制这个。代码如下:

var obj = {}; 
console.log(obj); 
obj.foo = 'bar';
// my outcome: Object{}; 'bar';
// The book outcome: {foo:bar};
如果这是异步的,我会预期结果将是books的结果。将console.log()放在事件队列中,直到执行所有代码,然后运行它,它将具有bar属性

它似乎是同步运行的


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

console.log
不是标准化的,因此行为没有定义,并且可以很容易地在不同版本的开发人员工具之间进行更改。你的书可能已经过时了,我的答案也可能很快就过时了

对于我们的代码来说,
console.log
是否异步没有任何区别,它不提供任何类型的回调等等;并且您传递的值总是在调用函数时被引用和计算

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

因此,控制台可以克隆(序列化)您记录的可变对象,也可以存储对它们的引用。第一种方法不适用于深/大对象。此外,至少控制台中的初始呈现可能会显示对象的“当前”状态,即登录时的状态-在您的示例中,您可以看到
object{}

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

以下是发布在中的屏幕截图,用于解释他们的“修复”:

因此,某些值可能在记录很久之后才被引用,而对这些值的计算相当缓慢(“在需要时”)。这种差异最著名的例子是在问题中处理的

解决方法是确保始终记录对象的序列化快照,例如通过执行
console.log(JSON.stringify(obj))
。不过,这只适用于非圆形和相当小的对象。另见


更好的解决方案是使用断点进行调试,在这里执行完全停止,您可以在每个点检查当前值。仅对可序列化和不可变的数据使用日志记录。

控制台。日志未标准化,因此行为未定义,并且可以在不同版本的开发人员工具之间轻松更改。你的书可能已经过时了,我的答案也可能很快就过时了

对于我们的代码来说,
console.log
是否异步没有任何区别,它不提供任何类型的回调等等;并且您传递的值总是在调用函数时被引用和计算

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

因此,控制台可以克隆(序列化)您记录的可变对象,也可以存储对它们的引用。第一种方法不适用于深/大对象。此外,至少控制台中的初始呈现可能会显示对象的“当前”状态,即登录时的状态-在您的示例中,您可以看到
object{}

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

以下是发布在中的屏幕截图,用于解释他们的“修复”:

因此,某些值可能在记录很久之后才被引用,而对这些值的计算相当缓慢(“在需要时”)。这种差异最著名的例子是在问题中处理的

解决方法是确保始终记录对象的序列化快照,例如通过执行
console.log(JSON.stringify(obj))
。不过,这只适用于非圆形和相当小的对象。另见


更好的解决方案是使用断点进行调试,在这里执行完全停止,您可以在每个点检查当前值。仅对可序列化和不可变数据使用日志记录。

使用console.log时:

a = {}; a.a=1;console.log(a);a.b=function(){};
// without b
a = {}; a.a=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);a.b=function(){};
// with b, maybe
a = {}; a.a=function(){};console.log(a);a.b=function(){};
// with b

在第一种情况下,对象足够简单,因此console可以“字符串化”它,然后呈现给您;但在其他情况下,a太“复杂”而无法“字符串化”,因此console将向您显示内存中的对象,是的,当您查看它时,b已连接到a。

使用console.log时:

a = {}; a.a=1;console.log(a);a.b=function(){};
// without b
a = {}; a.a=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);a.b=function(){};
// with b, maybe
a = {}; a.a=function(){};console.log(a);a.b=function(){};
// with b
在第一种情况下,对象足够简单,因此console可以“字符串化”它,然后呈现给您;但在其他情况下,a太“复杂”而无法“字符串化”,所以console会显示内存中的对象,是的,当您看到它时,b已经连接到a。

这不是真正的answ