-5

for (var i = 0; i < 10; i++) {
  setTimeout(function() {
    console.log(i);
  }, 100);
}

1 Answers1

1
for (var i = 0; i < 10; i++) {
  setTimeout(function() {
    console.log(i);
  }, 100);
}

немного отсебятины:

человеку с инженерным образованием может быть проще понять так:

  1. setTimeout - выполняется с задержкой (в данном случае в 100 мс)

  2. в цикле

    • объявление var выделяет одну "ячейку" в памяти и на эту одну и туже "ячейку" всегда ссылается переменная i

    • объявление let при каждой итерации выделяет новую "ячейку", таким образом переменная i на каждом шаге перебора цикла ссылается на новый адрес.


Я считаю нецелесообразным лезть в высокие материи и пытаться связать let и scope, а предлагаю просто запомнить, как один из частных случаев использования циклов (for/for-in/for-of -- var/let).


Qwerty_Wasd:

Возможный дубликат вопроса: Почему асинхронная функция внутри цикла выполняет последнюю итерацию много раз?

хотя ответ, данный Peter Olson, хорош и рассматривает различные способы решения проблемы - его возраст насчитывает три года. думаю на сегодняшний день es2015(не путать с es5) не только можно, но и нужно считать нижней планкой для изучения js, поэтому акцентирую внимает на использовании let.

let © https://learn.javascript.ru/let-const#let

3. При использовании в цикле, для каждой итерации создаётся своя переменная.

Переменная var – одна на все итерации цикла и видна даже после цикла:

for (var i = 0; i < 10; i++) { /* … */ }

alert(i); // 10

С переменной let – всё по-другому.

Каждому повторению цикла соответствует своя независимая переменная let. Если внутри цикла есть вложенные объявления функций, то в замыкании каждой будет та переменная, которая была при соответствующей итерации.

Это позволяет легко решить классическую проблему с замыканиями, описанную в задаче Армия функций.

function makeArmy() {

let shooters = [];

for (let i = 0; i < 10; i++) { shooters.push(function() { alert(i); // выводит свой номер }); }

return shooters; }

var army = makeArmy();

army0; // 0 army5; // 5

Если бы объявление было var i, то была бы одна переменная i на всю функцию, и вызовы в последних строках выводили бы 10 (подробнее – см. задачу Армия функций).

А выше объявление let i создаёт для каждого повторения блока в цикле свою переменную, которую функция и получает из замыкания в последних строках.

qwabra
  • 4,962