Вопрос проверяет понимание областей видимости, замыканий и причин типичных ошибок в асинхронных циклах.
При использовании var в цикле все асинхронные колбэки будут ссылаться на одну и ту же переменную. К моменту выполнения асинхронного кода цикл уже завершится, и переменная будет иметь финальное значение. В результате вместо ожидаемых разных значений выводится одно и то же. Это происходит из-за функциональной, а не блочной области видимости var.
Проблема возникает из-за сочетания замыкания и области видимости var.
Определение: Замыкание (closure) — это ситуация, когда функция “запоминает” переменные из внешней области видимости и продолжает иметь к ним доступ позже.
var в циклеvar имеет функциональную, а не блочную область видимости
в цикле создаётся одна переменная, а не новая на каждую итерацию
for (var i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i);
}, 100);
}
Что произойдёт:
Цикл выполнится полностью.
i станет равным 3.
Асинхронные колбэки выполнятся позже.
Все они выведут 3.
Разработчик интуитивно ожидает:
0
1
2
но получает:
3
3
3
setTimeout / setInterval
обработчики событий в циклах
промисы, создаваемые внутри цикла
Вывод: при использовании var в асинхронных циклах все колбэки разделяют одну переменную, поэтому получают одно и то же итоговое значение.