背景
修 bug 时,我常常用 console.log 去查看问题到底出在哪儿了。但当我打印一个对象时,经常不得不使用 JSON.stringify 去打印对象某个时刻的值。
比如:
let object = {a: 1}
console.log(object)
object.a++
执行结果是什么呢?
chrome 中,浅蓝色背景的 i
提示我:value below was evaluated just now.
我以前以为,出现这个现象的根本原因是,对象是一个引用。而从来没有思考过问题可能也出现在 console.log 这个方法身上。
console.log
https://developer.mozilla.org/zh-CN/docs/Web/API/Console/log
从文档可以看到,console.log 不属于任何公开的规范,事实上,不止 console.log ,对于整个 console.*
,都没有什么规范指定它们如何工作。
也就是说,console.* 并不是 javascript 正式的一部分,而是由宿主环境添加到 javascript 中的。
因此,不同的浏览器和 javascript 环境可以按照自己的意愿来实现。
而在某些浏览器里,console.log 并不会把传入的内容立即输出。因为在许多语言里,I/O 都是非常低速的阻塞部分。所以浏览器会选择在后台异步处理控制台 I/O ,以便提高性能。因此用户根本没有意识到这是个异步行为...
补充
什么时候浏览器控制台 I/O 会延迟,是不确定的,如果在调试过程中,对象在 console.log 语句之后被修改,导致你看到了意料之外的结果,要意识到这可能是 I/O 的异步化造成的。
解决方案:
- 使用断点调试
- 把对象序列化到字符串中输出