Chrome DevTools中>{}与>{key:value}的区别及重复打印对象异常咨询
嘿,这几个都是Chrome DevTools调试时很容易踩的小坑,我来给你一一拆解清楚!
一、控制台输入> {}和> {key:value}的本质区别
你可能会以为这俩都是创建对象,但JS语法解析在这里有个小陷阱:
- 当你输入
> {}时,DevTools会把它当成空代码块(就像if(){}里的大括号),而不是空对象字面量。所以控制台不会返回空对象,通常只会输出undefined。 - 输入
> {key: value}的时候,这里的key:其实是JS的标签语句(比如你写loop: for(...)时的标签),后面的value是一个独立的表达式。比如你输入> {foo: 123},控制台会返回123——因为它解析成标签foo:跟着表达式123,最后取的是表达式的结果。
如果想在控制台直接创建对象,得用括号把它包裹起来,让JS引擎把它当成表达式解析:> ({})或者> ({foo: 'bar'}),这样就能得到你想要的对象了。
二、同一函数链打印对象,日志显示不一致的原因
这绝对是DevTools最容易让人困惑的特性之一——惰性求值。
简单说:当你调用console.log(obj)时,DevTools并不会立刻把对象的所有属性拍个快照存下来,而是只记录一个指向该对象的引用。只有当你点击展开日志条目时,它才会去读取这个对象的当前状态。
关于那个i标志
你看到的小i图标,就是DevTools在提示你:这个日志条目是惰性求值的,你当前看到的预览(比如第一次的空括号)是打印那一刻的对象状态,但展开后看到的是对象的最新状态。
为什么展开前后/两次日志看起来不一样?
举个例子,假设你的代码是这样的:
const data = {}; console.log(data); // 第一次打印,此时data是空对象,预览显示{} // 函数链里的后续步骤修改了data data.id = 1; data.name = "test"; console.log(data); // 第二次打印,此时data已有属性,预览显示{id: 1, name: "test"}
当你展开第一次的日志时,DevTools会去读取data的最新状态(已经有id和name了),所以和第二次展开后的内容完全一致;而第一次的预览是打印时的快照,第二次的预览是修改后的快照,就出现了你看到的“展开前不一样,展开后一致”的情况。
你推测的“某个索引或属性未重置”其实是对的——你的函数链在两次打印之间,确实修改了同一个对象的内容,而DevTools的惰性求值放大了这个问题。
调试小技巧
如果想捕获对象打印时的真实状态,避免被后续修改干扰,可以用这几个方法:
- 深拷贝快照:
console.log(JSON.parse(JSON.stringify(obj))),这样会创建一个和原对象内容一致的新对象,后续修改原对象不会影响它。 - 存为全局变量:右键日志条目→Store as global variable,DevTools会把当时的对象存成
temp1/temp2这样的全局变量,你可以在控制台直接查看它的状态。 - 使用
console.dir():虽然和console.log类似,但有时候会更清晰地展示对象的结构,不过本质还是惰性求值,只是预览可能更准确。
内容的提问来源于stack exchange,提问作者ang
相关产品推荐
相关产品推荐

