Почему объект javascript показывает разные значения в консоли в Chrome, Firefox, Safari?

Возможный дубликат:
Является ли консоль JavaScript Chrome ленивой относительно оценки массивов?

Рассмотрим этот javascript:

var foo = {bar : 1111};
console.log(foo);
console.log(foo.bar);

foo.bar = 2222;
console.log(foo);
console.log(foo.bar);

В Firefox Firebug это показывает, что я ожидал:

Object { bar=1111}
1111

Object { bar=2222}
2222

Однако в браузере Safari и Chrome он показывает:

Object { bar=2222}
1111

Object { bar=2222}
2222

Другими словами, объект показывает неправильные атрибуты в консоли при печати, но правильное значение, если печатается конкретный атрибут.

Является ли это причудой браузеров? Или фундаментальный аспект объектно-ориентированного javascript, который мне не хватает?

Ответ 1

В Chrome (WebKit, поэтому Safari также), console.log вызовы с объектными аргументами регистрируют ссылку на объект. После щелчка и открытия вкладки объекта внутренности остаются постоянными (предположительно, кеш рода) и больше не связаны с объектом, на который первоначально ссылаются (так что если на более позднем этапе объект изменится, это не будет отражено). Однако до этого момента объект остается "незакрытым". Поэтому, когда вы регистрируете объект несколько раз, а затем открываете каждый зарегистрированный объект, все они указывают на тот же объект в памяти, значение которого является самым последним обновленным.

Это хорошо известная "проблема", хотя поведение является результатом дизайнерского решения (см. комментарии к первой ссылке) и поэтому не считается ошибкой команды разработчиков.

Легкие обходные пути - это любые средства для получения неъектного значения объекта, поэтому любой метод сериализации (например, console.log(JSON.stringify(foo));).

https://bugs.webkit.org/show_bug.cgi?id=35801
http://code.google.com/p/chromium/issues/detail?id=44720
http://code.google.com/p/chromium/issues/detail?id=50316