Почему 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 о том, что я хотел зарегистрировать.