Страницы

Поиск по вопросам

суббота, 7 декабря 2019 г.

Разница в поведении между let и var в цикле for

#javascript #ecmascript_6


Разница в объявлении счетчика цикла через let и var в том что через var переменная-счетчик
видна за пределами цикла в функции, через let - только в пределах цикла.
Объясните пожалуйста почему в этих случаях разные выводы

for(var i = 0; i < 10; i++) setTimeout(() => console.log(i), 1000)


тут получаем десять десяток.

for(let i = 0; i < 10; i++) setTimeout(() => console.log(i), 1000)


а тут от нуля до десяти.

С первым примером все понятно, а почему во втором так? i ведь создается один раз
и прокручивается до начала выполнения первого setInterval до десятки.
Одним словом - почему в эти двух примерах разные результаты?
    


Ответы

Ответ 1



https://learn.javascript.ru/let-const При использовании в цикле, для каждой итерации создаётся своя переменная. Переменная var – одна на все итерации цикла и видна даже после цикла. С переменной let – всё по-другому. Каждому повторению цикла соответствует своя независимая переменная let. Если внутри цикла есть вложенные объявления функций, то в замыкании каждой будет та переменная, которая была при соответствующей итерации.

Ответ 2



Все дело в области видимости переменной. Оператор let объявляет переменную которая приурочена к блочной области видимости. Что такое блочная область видимости? Вот пример let a = 10; { let a = 20; console.log(a); // 20 } console.log(a); // 10 Как видно внутри блока и вне его ES6 создает совершенно разные переменные. Переменная созданная оператором let видна только в своей области видимости и вне ее области видимости к ней обратиться не возможно. Вот что произойдет если то же самое попробовать с оператором var. var a = 10; { var a = 20; console.log(a); // 20 } console.log(a); // 20 Как видишь оператор var не полностью соответствует правилам блочной видимости. Можно твой пример можно упростить для большей ясности for(let i = 0; i < 10; i++) setTimeout(() => console.log(i), 1000) 1) Можно представить следующим образом for(let i = 0; i < 10; i++){ setTimeout( function(){console.log(i);}, 1000 ) } 2) И разбить по строкам { let i = 0; setTimeout( function(){console.log(i);}, 1000 ) } { let i = 1; setTimeout( function(){console.log(i);}, 1000 ) } { let i = 2; setTimeout( function(){console.log(i);}, 1000 ) } /** И так 10 раз .... После 1000 миллисекунд запуститься наша тайемр-функция, и поскольку в каждом блоке благодаря оператору let создавалась свая переменная то в таймер-функиции будет та переменная которая была создана в том же блоке.**/ Но с оператором var все обстоит иначе. { var i = 0; setTimeout( function(){console.log(i);}, 1000 ) } { var i = 1; setTimeout( function(){console.log(i);}, 1000 ) } { var i = 2; setTimeout( function(){console.log(i);}, 1000 ) } /** И так 10 раз ... Поскольку во всех блоках будет одна и та же переменная то после того как через 1000 миллисекунд запущенная таймер-функция прочитает последнее значение переменной i - которое у нас будет 10.**/ Как то вот так у нас обстоят дела с javascript. Больше о блочной области видимости можешь прочитать здесь и здесь.

Комментариев нет:

Отправить комментарий