Начну с кода:
var s = ["hi"];
console.log(s);
s[0] = "bye";
console.log(s);
Все просто, правда? В ответ на это Firebug говорит:
["hi"]
["bye"]
Замечательно, но консоль JavaScript Chrome (бета-версия 7.0.517.41) говорит:
["bye"]
["bye"]
Я сделал что-то не так, или консоль JavaScript Chrome исключительно ленива при оценке моего массива?
javascript
arrays
logging
google-chrome
console
Эрик Микельсен
источник
источник
i
всплывающая подсказка синего значка говорит: «Значение , указанное ниже, было оценено только что».Ответы:
Спасибо за комментарий, tec. Мне удалось найти существующую неподтвержденную ошибку Webkit, которая объясняет эту проблему: https://bugs.webkit.org/show_bug.cgi?id=35801 (EDIT: теперь исправлено!)
Кажется, есть некоторые споры относительно того, насколько это ошибка и можно ли ее исправить. Мне это действительно кажется плохим поведением. Меня это особенно беспокоило, потому что, по крайней мере, в Chrome, это происходит, когда код находится в сценариях, которые выполняются немедленно (до загрузки страницы), даже когда консоль открыта, всякий раз, когда страница обновляется. Вызов console.log, когда консоль еще не активна, приводит только к ссылке на объект, помещенный в очередь, но не к выходным данным, которые консоль будет содержать. Следовательно, массив (или любой объект) не будет оцениваться, пока консоль не будет готова. Это действительно случай ленивых вычислений.
Однако есть простой способ избежать этого в вашем коде:
Вызывая toString, вы создаете представление в памяти, которое не будет изменено следующими операторами, которые консоль прочитает, когда будет готова. Вывод консоли немного отличается от передачи объекта напрямую, но кажется приемлемым:
источник
По объяснению Эрика, он находится в
console.log()
очереди и выводит более позднее значение массива (или объекта).Возможных решений 5:
источник
Вы можете клонировать массив с помощью
Array#slice
:Функция, которую вы можете использовать вместо
console.log
нее, не имеет этой проблемы:В случае с объектами, к сожалению, лучшим методом является сначала отладка в браузере, отличном от WebKit, или создание сложной функции для клонирования. Если вы работаете только с простыми объектами, где порядок клавиш не имеет значения и нет функций, вы всегда можете сделать:
Все эти методы, очевидно, очень медленные, поэтому даже в большей степени, чем с обычными
console.log
s, вы должны удалить их после завершения отладки.источник
Это было исправлено в Webkit, однако при использовании среды React это происходит для меня в некоторых обстоятельствах, если у вас есть такие проблемы, просто используйте, как предлагают другие:
источник
JSON.parse(JSON.stringify(event))
не правильная глубина / точность. Операторы отладчика - единственное реальное решение, которое я нашел, чтобы получить правильное представление.На это уже есть ответ, но я все равно оставлю свой ответ. Я реализовал простую консольную оболочку, которая не страдает от этой проблемы. Требуется jQuery.
Он реализует только
log
,warn
иerror
методы, вам придется добавить еще немного для того , чтобы быть взаимозаменяемыми с регулярнымconsole
.источник
Похоже, Chrome заменяет на этапе «предварительной компиляции» любой экземпляр «s» указателем на фактический массив.
Один из способов - клонировать массив, вместо этого записывая новую копию:
источник
на данный момент самым коротким решением является использование синтаксиса распределения массива или объекта, чтобы получить клон значений, которые будут сохранены во время регистрации, то есть:
однако имейте в виду, что это неглубокая копия, поэтому любые глубоко вложенные непримитивные значения не будут клонированы и, таким образом, показаны в их измененном состоянии в консоли
источник