console.log
не стандартизовано, тому поведінка досить невизначена і може бути легко змінена від випуску до випуску інструментів розробника. Ваша книга, швидше за все, застаріла, як і моя відповідь найближчим часом.
Для нашого коду це не має значення console.log
, асинхронний чи ні, він не передбачає жодного зворотного дзвінка або близько того; а передані вами значення завжди посилаються та обчислюються під час виклику функції.
Ми насправді не знаємо, що відбувається тоді (добре, ми могли б, оскільки Firebug, Chrome Devtools та Opera Dragonfly - це всі відкриті джерела). Консолі потрібно буде десь зберігати зареєстровані значення, і вона відображатиме їх на екрані. Візуалізація відбуватиметься точно асинхронно (з обмеженням до обмежень швидкості), як і майбутні взаємодії із зареєстрованими об'єктами в консолі (наприклад, розширення властивостей об'єкта).
Отже, консоль може або клонувати (серіалізувати) змінні об’єкти, які ви реєстрували, або вона буде зберігати посилання на них. Перший погано працює з глибокими / великими об’єктами. Крім того, принаймні початковий візуалізація в консолі, ймовірно, відображатиме "поточний" стан об'єкта, тобто той, коли він був зареєстрований - у вашому прикладі ви бачите Object {}
.
Однак, коли ви розгортаєте об'єкт для подальшого перевірки його властивостей, цілком ймовірно, що консоль буде зберігати лише посилання на ваш об'єкт та його властивості, а їх відображення тепер відображатиме їх поточний (вже змінений) стан. Якщо натиснути на +
, ви зможете побачити bar
властивість у вашому прикладі.
Ось знімок екрана, який був опублікований у звіті про помилку, щоб пояснити їх "виправлення":
Отже, на деякі значення можна посилатися ще довго після їх реєстрації, і їх оцінка є досить лінивою ("коли потрібно"). Найвідоміший приклад цієї розбіжності розглядається у питанні Чи лежить консоль JavaScript на Chrome щодо оцінки масивів?
Вирішення полягає в тому, щоб завжди реєструвати серіалізовані знімки ваших об’єктів, наприклад, виконуючи console.log(JSON.stringify(obj))
. Однак це буде працювати лише для некруглих і досить дрібних об'єктів. Див. Також Як я можу змінити поведінку за замовчуванням console.log у Safari? .
Кращим рішенням є використання точок зупинки для налагодження, де виконання повністю зупиняється, і ви можете перевірити поточні значення в кожній точці. Використовуйте журналювання лише із серіалізованими та незмінними даними.