Почему console.log() не делает снимок прошедших переменных?

Я столкнулся с каким-то действительно странным поведением с 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);

Код в jsFiddle

Результатом этого является что-то вроде (в зависимости от браузера):

> Object
50

Если вы развернете "Объект" (в Chrome, Safari или Firefox (Firebug), вы получите:

> Object
    left: 0
    top: -50

В то время как я ожидал бы:

> Object
    left: 50
    top: -50

То, что я думаю, это то, что console.log() действительно просто "отправляет" ссылку на консоль, которая считывается после нажатия на символ "expand". Но не такое ли поражение цели console.log() как инструмент отладки? Я всегда ожидал, что console.log() "снимет" материал, который я передаю ему. На самом деле удивительно видеть утверждение, которое возникает после того, как фактический console.log() изменит вывод этого самого вызова console.log().

Или есть что-то еще?

Изменить: Мне также интересно, есть ли разумная причина для разработчиков браузеров для реализации console.log, как это (я думаю, есть один, иначе он не будет согласован в основных браузерах).

Ответ 1

В Firebug есть console.dir() для того, что вы хотите.

В общем случае невозможно напечатать каждый уровень вложенных свойств, поскольку объекты могут содержать циклические ссылки, такие как var a = {}; var b = {a: a}; a.b = b;

Реализация идеального метода clone очень сложна - я думаю, что это должно было бы просто сбрасывать всю память, и запись была бы ужасно длинной. Подумайте о console.log(window)...

Ответ 2

Да, это то, что происходит. Я бы предположил, что это сделано для минимизации накладных расходов на вызовы console.log(). Вещи могут выйти из-под контроля, если каждый объект был глубоко клонирован для каждого вызова журнала.

Когда мне нужно обходить это, я либо JSON.stringify(), либо мелкий клонирует объект, прежде чем передать его на console.log().

Ответ 3

Я также видел это поведение, и он уверен, что ссылка опубликована. Чтобы обойти это, я использовал метод clone() в jQuery о том, что я хотел зарегистрировать.