Подтвердить что ты не робот

Google Chrome console.log() несогласованность с объектами и массивами

Я помогал коллеге отлаживать некоторый код сегодня, и я заметил странное поведение с console.log() в Google Chrome:

Похоже, что если вы:

  • Создайте вложенный массив (например, [[345, "test" ]])

  • Запишите массив в консоль с помощью console.log().

  • Измените одно из значений внутреннего массива, затем console.log() выведет значение ниже - not значения массива в момент выполнения console.log().

JavaScript

var test = [[2345235345,"test"]]
console.log(test);
test[0][0] = 1111111;
// outputs: [[1111111,"test"]]

var testb = {};
testb.test = "test";
console.log(testb);
testb.test = "sdfgsdfg";
// outputs: {"testb":"test"}


var testc = ["test","test2"];
console.log(testc);
testc[0] = "sdxfsdf";
// outputs: ["test","test2"]

Пример JSFiddle

Такое поведение не происходит в Firefox.

Также следует отметить, что если бы я выполнил свой код по строкам в отладчике Chrome, то console.log() выдаст правильные значения.

Есть ли объяснение этому странному явлению или это просто ошибка с Google Chrome?

EDIT:

Я сузил шаги, чтобы воспроизвести непоследовательное поведение console.log():

Если вы добавите этот script на свою страницу:

var greetings=['hi','bye'];
console.log(greetings);
setTimeout(function(){
    greetings.push('goodbye');
},3000);

и откройте его в новом окне с открытым окном консоли Chrome , то вывод console.log() будет отличаться, если вы загрузите страницу с закрытым окном strong > . Здесь показан JSFiddle, который показывает.

В первом случае, когда консольное окно уже открыто, console.log() выведет текущее значение массива (т.е. два элемента).

Во втором случае, когда консольное окно первоначально закрыто и открыто только после загрузки страницы, console.log() выдаст более поздние значения массива (т.е. три элемента).

Является ли это ошибкой в ​​функциях Google Chrome console.log()?

4b9b3361

Ответ 1

После большого поиска, я обнаружил, что это было сообщено как ошибка, исправленная в Webkit, но, видимо, еще не втянута в Google Chrome.

Насколько я могу судить, проблема была первоначально сообщена здесь: https://bugs.webkit.org/show_bug.cgi?id=35801:

Описание От mitch kramer 2010-03-05 11:37:45 PST

1) создать литерал объекта с одним или несколькими свойствами

2) console.log этот объект, но оставьте его закрытым (не расширяйте его в консоли)

3) измените одно из свойств на новое значение

теперь откройте этот console.log, и вы увидите, что по какой-то причине оно имеет новое значение, даже несмотря на то, что при его создании значение было другим.

Я должен указать, что если вы его откроете, он сохранит правильное значение, если это не ясно.

Отклик от разработчика Chromium:

Комментарий № 2 от Pavel Feldman 2010-03-09 06:33:36 PST

Я не думаю, что мы когда-нибудь это исправим. Мы не можем клонировать объект при сбрасывании его в консоль, и мы также не можем слушать изменения свойств объекта, чтобы сделать его всегда актуальным.

Мы должны убедиться, что ожидаемое поведение ожидается.

Исправление было реализовано два с половиной года спустя 9 августа 2012 года для Webkit (http://trac.webkit.org/changeset/125174), но это похоже, пока не попали в Chrome.

На сегодняшний день сброс объекта (массива) в консоль приведет к тому, что свойства объекта будут читайте о расширении объекта консоли (т.е. лениво). Это означает, что сброс одного и того же объекта во время мутация будет сложной для отладки с помощью консоли.

Это изменение начинает генерировать сокращенные превью для объектов/массивов в момент их регистрирует и передает эту информацию в интерфейсный модуль. Это происходит только тогда, когда интерфейс уже открыт, он работает только для console.log(), а не для взаимодействия с консолью.

Ответ 2

Я нашел обходной путь для этой ошибки/функции.

console.log(JSON.parse(JSON.stringify(myObject)));

Изменить: К сожалению, это не будет работать для не-примитивных значений, таких как функции. Используйте другую утилиту для клонирования.

Пример jQuery:

console.log($.extend({}, myObject));