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

时间:2011-03-07 18:20:25

标签: 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);

The code at jsFiddle

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

> Object
50

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

> Object
    left: 0
    top: -50

我希望:

> Object
    left: 50
    top: -50

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

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

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

3 个答案:

答案 0 :(得分:11)

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

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

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

答案 1 :(得分:10)

是的,这是正在发生的事情。我猜这样做是为了尽量减少console.log()次调用的开销。如果每个对象都被深度克隆用于每次日志调用,事情就会失控。

当我需要解决此问题时,我要先JSON.stringify()或浅层对象,然后再将其传递给console.log()

答案 2 :(得分:6)

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

相关问题