console.log
не стандартизирован, поэтому поведение скорее неопределенное, и его можно легко изменить от выпуска к выпуску инструментов разработчика. Ваша книга, вероятно, устарела, как и мой ответ в ближайшее время.
Для нашего кода не имеет значения, console.log
является ли он асинхронным или нет, он не обеспечивает какого-либо обратного вызова или чего-то подобного; и значения, которые вы передаете, всегда ссылаются и вычисляются во время вызова функции.
Мы действительно не знаем, что происходит потом (хорошо, мы могли бы, поскольку Firebug, Chrome Devtools и Opera Dragonfly имеют открытый исходный код). Консоль должна будет где-то хранить зарегистрированные значения, и она будет отображать их на экране. Рендеринг обязательно будет происходить асинхронно (дросселируется до обновлений ограничения скорости), как и будущие взаимодействия с зарегистрированными объектами в консоли (например, расширение свойств объекта).
Таким образом, консоль может либо клонировать (сериализовать) изменяемые объекты, которые вы записали в журнал, либо сохранять ссылки на них. Первый не работает с глубокими / большими объектами. Кроме того, по крайней мере, первоначальный рендеринг в консоли, вероятно, покажет «текущее» состояние объекта, то есть то, когда он был зарегистрирован - в вашем примере вы видите Object {}
.
Однако, когда вы расширяете объект для дальнейшего изучения его свойств, вполне вероятно, что консоль сохранит только ссылку на ваш объект и его свойства, и при их отображении будет показано их текущее (уже измененное) состояние. Если вы нажмете на +
, вы должны увидеть bar
свойство в своем примере.
Вот скриншот, который был опубликован в отчете об ошибке, чтобы объяснить их «исправление»:
Таким образом, на некоторые значения можно ссылаться спустя долгое время после того, как они были зарегистрированы, и их оценка довольно ленивая («при необходимости»). Самый известный пример этого несоответствия рассматривается в вопросе "Ленится ли консоль JavaScript Chrome оценивать массивы?"
Обходной путь - всегда записывать сериализованные снимки ваших объектов, например, путем выполнения console.log(JSON.stringify(obj))
. Однако это будет работать только для некруглых и довольно маленьких объектов. См. Также Как изменить поведение console.log по умолчанию в Safari? .
Лучшее решение - использовать точки останова для отладки, когда выполнение полностью останавливается, и вы можете проверить текущие значения в каждой точке. Используйте ведение журнала только для сериализуемых и неизменяемых данных.