对象和 console.log 的奇怪行为

IT技术 javascript google-chrome object
2021-01-19 19:26:20

这段代码:

foo = [{id: 1},{id: 2},{id: 3},{id: 4}, {id: 5}, ];
console.log('foo1', foo, foo.length);
foo.splice(2, 1);
console.log('foo2', foo, foo.length);

在 Chrome 中产生以下输出:

foo1 
[Object, Object, Object, Object, Object]  5
    0: Object
    1: Object
    2: Object
    3: Object
    length: 4
    __proto__: Array[0]
     5 (index):23
foo2 
[Object, Object, Object, Object]  4
    0: Object
    1: Object
    2: Object
    3: Object
    length: 4
    __proto__: Array[0]

小提琴:http : //jsfiddle.net/2kpnV/

这是为什么?

2个回答

通过console.log以异步方式检查对象控制台同步接收对对象的引用,但在对象展开之前不会显示对象的属性(在某些情况下,取决于浏览器以及日志发生时您是否打开了开发工具)。如果对象在控制台中检查之前已被修改,则显示的数据将具有更新的值。

例如,Chrome 会i在一个框中显示一点,当鼠标悬停时,它会显示

记录时对左侧的对象值进行了快照,下面的值刚刚评估。

让你知道你在看什么。

在这些情况下记录的一个技巧是记录各个值:

console.log(obj.foo, obj.bar, obj.baz);

或 JSON 编码对象引用:

console.log(JSON.stringify(obj));
或: console.log( Object.assign({}, obj) ); - 这将创建对象的新副本。
2021-03-16 19:26:20
如另一个答案中所述,JSON.parse(JSON.stringify(obj))将日志视为 json 对象而不是字符串可能会更好
2021-03-17 19:26:20
Chrome 这样做而不是显示记录时的值的原因是什么?那不是更有用吗?
2021-03-23 19:26:20
@Peter - 我部分错了,Object.assign仅适用于仅包含原始值的对象(因为Object.assign制作浅拷贝,而不是深拷贝)。如果obj包含另一个对象,则该嵌套对象的值将被单独“评估”。
2021-03-25 19:26:20
@cimak,出于某种原因,我仍然得到一个对象,该对象在使用console.log(Object.assign({}, obj)). Usingconsole.log( JSON.parse(JSON.stringify(obj)) )确实显示输出时的值。
2021-03-31 19:26:20

重新定义console.log将解决问题。

var originalLog = console.log;
console.log = function(obj) {
    originalLog(JSON.parse(JSON.stringify(obj)));
};
它不是很有用,因为在控制台中它将显示定义此函数的行数而不是我调用 console.log 的实际行
2021-03-29 19:26:20