为什么console.log()没有传递传递的变量的快照?

时间:2021-07-09 16:55:13

I've ran into some really weird behavior with javascript today. I think I got it somehow figured out now, but I'd like to know if what I think is going on is really happening or if there is some other magic involved. So this is my code:

今天我用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

jsFiddle的代码

The output of this is something like (depending on the browser):

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

> Object
50

If you expand the "Object" (in Chrome, Safari or Firefox (Firebug) what you get is:

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

> Object
    left: 0
    top: -50

Whereas I would expect:

我希望:

> Object
    left: 50
    top: -50

What I think is going on is that console.log() really just "posts" a reference to the console, which gets read once you click on the "expand" symbol. But doesn't that kind of defeat the purpose of console.log() as a debugging instrument? I always expected console.log() to "snapshot" the stuff I pass to it. It is really surprising to see a statement which comes after the actual console.log() change the output of that very console.log() call.

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

Or is there something else going on?

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

Edit: I'm also wondering if there is a sound reason for browser developers to implement console.log like this (I guess there is one, otherwise it wouldn't be consistent across major browsers).

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

3 个解决方案

#1


10  

There is console.dir() for what you want in Firebug.

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

In general, it is not possible to print every level of nested properties, since objects can contain circular references like var a = {}; var b = {a: a}; a.b = b;

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

Implementing a perfect clone method is very hard - I guess it would have to basically just dump the whole memory, and logging would take awfully long. Think about console.log(window)...

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

#2


9  

Yes, this is what's going on. I would guess it's done to minimize the overhead of console.log() calls. Things could get out of control if every object was deep cloned for every log call.

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

When I need to workaround this, I either JSON.stringify() or shallow clone the object before passing it to console.log().

当我需要解决这个问题时,我将JSON.stringify()或浅层克隆该对象,然后再将其传递给console.log()。

#3


6  

I've also seen this behavior and it sure looks like a reference is posted. To get around this I used the clone() method in jQuery on the things I wanted to log.

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

#1


10  

There is console.dir() for what you want in Firebug.

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

In general, it is not possible to print every level of nested properties, since objects can contain circular references like var a = {}; var b = {a: a}; a.b = b;

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

Implementing a perfect clone method is very hard - I guess it would have to basically just dump the whole memory, and logging would take awfully long. Think about console.log(window)...

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

#2


9  

Yes, this is what's going on. I would guess it's done to minimize the overhead of console.log() calls. Things could get out of control if every object was deep cloned for every log call.

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

When I need to workaround this, I either JSON.stringify() or shallow clone the object before passing it to console.log().

当我需要解决这个问题时,我将JSON.stringify()或浅层克隆该对象,然后再将其传递给console.log()。

#3


6  

I've also seen this behavior and it sure looks like a reference is posted. To get around this I used the clone() method in jQuery on the things I wanted to log.

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