为何未展开的console.log输出会被更新?技术求助
控制台日志显示异常问题解决
问题场景
点击重置按钮触发函数后,控制台立刻输出FIRST日志,此时展开能看到包含5个对象的数组;5秒后输出SECOND日志,显示空数组,流程本身没问题。但如果点击重置后先不展开FIRST日志,等5秒后再展开,会发现FIRST和SECOND日志都显示空数组,就像FIRST日志被修改了一样。实际函数逻辑正常,只有console.log存在这个异常表现。
相关代码:
reset: () => { console.log("FIRST", world.bodies) setTimeout(() => { for (let i = 0; i < objectBoxToUpdate.length; i++) { const rigidBody = objectBoxToUpdate[i].rigidBodyBox world.removeRigidBody(rigidBody) } console.log("SECOND", world.bodies) }, 5000) }
问题原因
这不是代码bug,是浏览器控制台的特性导致的:当用console.log输出引用类型(比如数组、对象)时,控制台并不会立即生成对象的完整快照,只是保存一个指向该对象的引用。只有当你手动展开日志的时候,控制台才会读取这个对象的当前状态。所以等5秒后world.bodies被清空,再展开FIRST日志,看到的就是已经被修改后的空数组。
解决方法
要输出对象的静态快照,避免后续修改影响日志显示,有几种常用方式:
深拷贝后输出:创建原对象的深拷贝再打印。如果是简单数组,可用扩展运算符实现浅拷贝:
console.log("FIRST", [...world.bodies])若是多层嵌套对象,可通过
JSON.parse(JSON.stringify(world.bodies))实现深拷贝(注意这种方式不支持函数、Symbol等特殊类型):console.log("FIRST", JSON.parse(JSON.stringify(world.bodies)))使用
console.table:如果数组内对象结构规整,console.table会直接打印出对象的静态快照:console.table(world.bodies)打印具体属性:如果只关注对象的部分属性,直接打印这些属性值而非整个对象引用。
内容的提问来源于stack exchange,提问作者Igor-Vuk
相关产品推荐
相关产品推荐

