2016-01-10 2 views
11

Рассмотрим следующий фрагменты кодаЗачем «для (а)» правильно итерации массива?

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, но я смущен следующего утверждения.

для (вар ForBinding из ВыраженияПрисваивания) Заявление

для (ForDeclaration из ВыраженияПрисваивания) Заявление

Для понимания 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)?

ответ

9

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

Наличие var: for (a of ...) и for (var a of ...) не делает никакой разницы в коде, как вы уже 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 
+0

Это, кажется, единственный ответ, который фактически решает вопрос и, по-видимому, также является единственным правильным ответом. Не уверен, почему кто-то другой дал ему нисходящее движение. +1 от меня. – jfriend00

+6

Я не проголосовал, но переменные, объявленные с помощью 'var', не были повторно объявлены. Объявления отображаются в их объеме, а 'var' встречается позже в коде _ignored_. – Teemu

+1

@Teemu да, мое утверждение действительно упрощает и вместо этого должно быть «если вы используете версию« var a », значение« a »до и после цикла будет по-прежнему одинаковым, но оно может затенять переменные из внешней области из-за подъема (и, следовательно, полностью изменить то, что вы повторяете) ». –

Смежные вопросы