为什么console.log()不对传递的变量进行快照?

fre*_*oma 19 javascript debugging console

今天我用javascript遇到了一些非常奇怪的行为.我想我现在已经弄明白了,但我想知道我认为发生的事情是否真的发生了,或者是否还有其他一些魔法.所以这是我的代码:

    var SomeObject = {};

    SomeObject.foo = function(a, b) {
       var baz = this.bar(a, b);
       console.log(baz);
       console.log(baz.left);
       SomeObject.magicalStuff(baz);
    };

    SomeObject.bar = function(a, b) {
        return {left: a-b, top: b-a};
    };

    SomeObject.magicalStuff = function(position) {
        position.left = 0;
    };

    SomeObject.foo(100, 50);
Run Code Online (Sandbox Code Playgroud)

jsFiddle的代码

这个输出类似于(取决于浏览器):

> Object
50
Run Code Online (Sandbox Code Playgroud)

如果您展开"对象"(在Chrome,Safari或Firefox(Firebug)中,您得到的是:

> Object
    left: 0
    top: -50
Run Code Online (Sandbox Code Playgroud)

我希望:

> Object
    left: 50
    top: -50
Run Code Online (Sandbox Code Playgroud)

我的想法是,console.log()实际上只是"发布"对控制台的引用,一旦你点击"展开"符号就会被读取.但是那种打败console.log()作为调试工具的目的不是那样吗?我总是希望console.log()能够"快照"我传递给它的东西.看到实际的console.log()改变了那个console.log()调用的输出之后的声明,真是令人惊讶.

或者还有其他事情发生了吗?

编辑:我也想知道浏览器开发人员是否有合理的理由来实现这样的console.log(我猜有一个,否则它在主流浏览器中不一致).

use*_*621 11

console.dir()Firebug中有你想要的东西.

通常,不可能打印每个级别的嵌套属性,因为对象可以包含循环引用var a = {}; var b = {a: a}; a.b = b;

实现一个完美的clone方法非常困难 - 我想它基本上只需要转储整个内存,并且日志记录将花费很长时间.想想console.log(window)......


Nat*_*ard 10

是的,这是正在发生的事情.我猜这是为了最大限度地减少console.log()呼叫的开销.如果为每个日志调用深度克隆每个对象,事情就会失控.

当我需要解决这个问题时,我要么JSON.stringify()在传递它之前对其进行浅层克隆console.log().


jim*_*mig 6

我也看到过这种行为,它确实看起来像是一个参考文章.为了解决这个问题,我在jQuery中使用了clone()方法来记录我想要记录的内容.