Консоль JavaScript печатает назначенное значение переменной до ее назначения?

Я глубоко смущен поведением JavaScript или консоли Chrome. Может ли кто-нибудь помочь мне понять?

В основном у меня есть следующий код JavaScript, не вложенный внутри какой-либо функции или другой области:

var initial_array = [];

function initialiseArray() { 
   initial_array = [2, 9, 8, 6, 0, 2, 1];
} 

function copyToNewArray() {
    var copied_array = [];

    console.log("COPIED 1", copied_array);

    for (var i = 0; i < initial_array.length; i++) {
        var copy = initial_array[i];
        copied_array.push(copy);
    }

    console.log("COPIED 2", copied_array);
}

initialiseArray();
copyToNewArray();

Я ожидал бы COPIED 1 для печати [] - поскольку переменная еще не назначена, но вместо этого она печатает [2, 9, 8, 6, 0, 2, 1] - то есть значение после того, как оно было назначено.

Почему?

Кстати, если вы заменяете строки 8-11 на initial_array = copied_array, то RESULTS 1 действительно печатается как []. Это как-то связано с использованием .push?

Ответ 1

Попробуйте отладить свою проблему в отладчике Chrome script. Поместите точку останова на строку:

for (var i = 0; i < initial_array.length; i++) {

и вы увидите желаемое поведение.

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

Ответ 2

Так как массивы передаются по ссылке, каждое изменение, которое вы делаете, изменяет то, что выводится в консоли. Отчасти это поведение консоли Chrome, частично JavaScript.

Если вы хотите распечатать результат во время вызова console.log, вы можете вывести его как строку с помощью JSON.stringify.

console.log("COPIED 1", JSON.stringify(copied_array));

Важное изменение

Кажется, я был в основном неправильным. Как отмечал ДиЭо в комментариях к вопросу, похожий вопрос имеет лучший ответ. Кажется, это только поведение Chrome.

Ответ 3

console.log("COPIED 1", JSON.stringify(copied_array));

Должно быть хорошо для отладки


это ошибка, о которой вы говорили, см. ниже

https://bugs.webkit.org/show_bug.cgi?id=35801

также читали похожие вопросы

Является ли консоль JavaScript Chrome ленивой относительно оценки массивов?

Необычное поведение console.log в инструментах разработчика Chrome

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

Ответ 4

Это то, как массивы отображаются в консоли Chrome, и это по ссылке. Если вы хотите получить точные результаты, конвертируйте в строку:

var initial_array = [];

function initialiseArray() { 
   initial_array = [2, 9, 8, 6, 0, 2, 1];
} 

function copyToNewArray() {
    var copied_array = [];

    console.log("COPIED 1", copied_array.toString());

    for (var i = 0; i < initial_array.length; i++) {
        var copy = initial_array[i];
        copied_array.push(copy);
    }

    console.log("COPIED 2", copied_array.toString());
}

initialiseArray();
copyToNewArray();

Вы можете легко проверить это:

var x = [];
console.log(x), x.push(5), x; // outputs [5] and [5]

Ответ 5

Консоль фактически асинхронна. Поскольку вы регистрируете ссылку на объект, к моменту регистрации объекта он уже изменился.

Вы можете клонировать массив, прежде чем регистрировать его, чтобы быть уверенным, что он не будет изменен до его регистрации.

Ответ 6

var initial_array = [];
 function initialiseArray() { 
   initial_array = [2, 9, 8, 6, 0, 2, 1];
} 
function copyToNewArray() {
    var copied_array = [];
    console.log("COPIED 1", copied_array);
    alert(copied_array.length);
    for (var i = 0; i < initial_array.length; i++) {
        var copy = initial_array[i];
        copied_array.push(copy);
    }
    console.log("COPIED 2", copied_array);
}
initialiseArray();
copyToNewArray();

Добавление строки alert(copied_array.length); покажет правильные результаты.

Случается, что журнал не синхронизируется с выполнением javascript. Когда журнал печатает, значения уже были изменены.

Ответ 7

потому что copied_array является ссылкой, а console.log выполняется несинхронно, поэтому содержимое массива модифицируется до того, как будет напечатан первый журнал.

вы можете скопировать массив перед печатью

console.log([].concat(copied_array));

Ответ 8

Если вы хотите сохранить функции консоли, такие как расширение объектов в массиве, я предлагаю использовать .slice, который делает копию массива, которая не изменяется при регистрации:

console.log("COPIED 1", copied_array.slice());