为什么 console.log() 和 console.dir() 记录尚不存在的对象属性?

Why are console.log() and console.dir() logging Object properties that don't exist yet?

测试以下内容:

var o = {};
console.log(o);
o.prop = 'value';

在 Firefox 42.0 中,如果您单击控制台中显示的对象,您应该会感到震惊。在 Firebug 2.0.13 以及常规控制台中测试。

更震撼,测试一下:

var o = {prop:'test'};
console.log(o);
o.prop = 'value';

我无法在最新的 Microsoft Edge 中使用上面的代码重现此问题,但我能够使用更广泛的代码产生相同的问题。

使用更大的面向对象 JavaScript 程序 (使用构造函数),我还用 console.dir() 测试了这个并且在 Microsoft 中遇到了同样的提升问题Edge 和 Firefox。

这是一个错误吗?

只是评论:

var o = {};
console.log('logged' + o);
o.prop = 'value';

结果:

logged Object {}
"value"

那么,您在哪里可以看到它的日志记录 'value'?

您一定对 console.log()console.dir() 函数感到困惑。

console.log(o) 打印对象引用。因此,当您在控制台中展开它时,您会看到到目前为止已完成的所有更新

console.dir(o)就像当时参考的快照。这样您将无法在控制台中看到稍后完成的更新

这不是一个错误,虽然它可以被认为是不直观的。当您检查一个记录的对象时,您是在检查它 当前存在的状态 而不是您记录它时的状态。为了让丰富的检查 忽略未来的修改,您必须记录对象的深层副本,这并不容易。

在这个例子中,一个快速的(仅可枚举的自己的属性到一个新的Object)浅拷贝是有效的,但是:

function copyObject(obj) {
    var result = {};

    Object.keys(obj).forEach(function (key) {
        result[key] = obj[key];
    });

    return result;
}

var o = {};
console.log(o);
console.log(copyObject(o));
o.prop = 'value';