如何让Google Chrome中的console.log实现同步工作?
这个问题我之前调试的时候也踩过坑,Chrome控制台的这个特性确实容易让人误以为代码逻辑出问题了😅。你推测的原因完全正确:Chrome的console.log对于数组、对象这类引用类型,并不会在调用时立即生成值的快照,而是等你手动展开控制台面板的时候,才去读取该引用的当前值——这就导致你修改了对象属性后,看到的是修改后的结果。而console.table会在调用时就把数据序列化,所以能正确显示当时的状态。
下面给你几个实用的方法,让console.log也能实现同步显示的效果:
深拷贝生成快照(最通用):
用JSON.stringify把对象/数组转成JSON字符串,再用JSON.parse解析回来,这样就能得到一个和原引用完全独立的副本,打印这个副本就不会受后续修改的影响:var array = [{a: 0}]; console.log(JSON.parse(JSON.stringify(array))); // 打印的是修改前的[{a: 0}] array[0].a = 1;这个方法适合所有层级的嵌套对象,唯一的小缺点是如果对象里包含
undefined、函数或者循环引用,JSON.stringify会忽略或报错,不过日常调试里这种场景不多见。浅拷贝快速生成副本(适合简单结构):
对于没有深层嵌套的数组或对象,可以用展开运算符快速创建一个浅拷贝的副本:var array = [{a: 0}]; console.log([...array]); // 浅拷贝数组,打印当时的状态 array[0].a = 1;注意:如果数组里的对象还有嵌套的引用类型(比如
[{a: {b: 0}}]),浅拷贝的副本里的嵌套对象还是和原对象共享引用,修改b的值还是会影响打印结果,这种情况还是用上面的深拷贝方法更稳妥。直接打印基本类型属性:
如果只关心对象里的某个基本类型属性,可以直接打印该属性,基本类型是值传递,会立即显示调用时的状态:var array = [{a: 0}]; console.log(array[0].a); // 直接打印0,不受后续修改影响 array[0].a = 1;调试时用断点暂停:
如果你只是在调试阶段想查看当时的状态,可以在console.log之后加一个debugger语句,浏览器会暂停代码执行,此时展开控制台就能看到console.log调用时的对象状态了:var array = [{a: 0}]; console.log(array); debugger; // 暂停在这里,展开控制台就能看到[{a: 0}] array[0].a = 1;
内容的提问来源于stack exchange,提问作者Danyg

