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

Почему "для a (a)" правильно итерации массива?

Рассмотрим следующие фрагменты кода

var a = [1, 2, 3, 4];
for (a of a) { // The first 'a' is made by mistake
    console.log(a);
}

Первый a в цикле for написан по ошибке. Я думаю, что вышеприведенный код должен запускать ошибку, потому что когда a назначается 1 в первой итерации, тогда a не является итерируемым объектом. Поэтому на следующей итерации должна быть выброшена ошибка.

Фактически, результаты следующие:

1
2
3
4

Кажется, что приведенный выше код может правильно итерации массива. После цикла for результат a равен 4. Почему?

> a
4

Для дальнейшего исследования я попытался найти некоторую информацию из ECMA-6 doc, но меня смущает следующая инструкция.

for (var ForBinding of AssignmentExpression) Statement

for (ForDeclaration of AssignmentExpression) Statement

Чтобы понять ForBinding и ForDeclaration, проверьте следующий код.

var a = [1, 2, 3, 4];
for (var a of a) {
    console.log(a);
}
console.log(a);

К сожалению, результат такой же, как и предыдущие коды. В чем разница между for (var a in a) и for (a in a)?

4b9b3361

Ответ 1

for оценивает значение "AssignmentExpression" и выполняет итерацию по нему. Значение получается только один раз в начале итерации, поэтому повторное использование одной и той же переменной вполне допустимо (также довольно запутанно).

Присутствие var: for (a of ...) и for (var a of ...) не делает различий в 1 в коде, поскольку у вас уже есть a, поэтому он просто повторно объявит одну и ту же переменную,


Чтобы быть точным, существуют случаи, когда поведение отличается - когда a объявляется во внешней области для текущей функции var версия будет теневое это значение (как в JavaScript все инструкции var поднимаются на вершину ):

var a = [1,2,3];
function tryForVar()   {
   // Note that declaration of `a` is hoisted here as var a = undefined;
   // for (var a ... does not work as expected as local 'a' is undefined
   for (var a of a) { 
     console.log(a); // log 'undefined' once
   }
   console.log(a); // undefined 
} 
tryForVar();
console.log(a); // [1,2,3]

function tryFor()   {
   // Note that declaration of `a` from outer scope
   // for (a ... works fine as it uses outer 'a'
   for (a of a) { 
     console.log(a); // logs all 1,2,3 in sequence
   }
   console.log(a); // 3
} 
tryFor();
console.log(a); // 3