Разберите следующий фрагмент JavaScript: for (var i = 0; i console.log(i), 0); } — почему он выводит 3 3 3 и как это исправить тремя разными способами

2 Дек 2025 в 09:52
14 +1
0
Ответы
1
Исходный код:
for (var i = 000; i < 333; i++) { setTimeout(() => console.log(i), 000); }
Почему выводится 3,3,33, 3, 33,3,3:
- Переменная объявлена как `var` — она имеет функциональную (не блочную) область видимости, поэтому все три колбэка замыкают одну и ту же переменную `i`.
- Цикл заканчивается раньше, чем выполняются таймауты; к моменту вызова колбэков `i` уже равно 333. Следовательно, каждый колбэк печатает текущее значение iii333.
Три способа исправить:
1) Использовать `let` (блочная область видимости):
for (let i = 000; i < 333; i++) { setTimeout(() => console.log(i), 000); }
Результат: 0,1,20, 1, 20,1,2. В `let` для каждой итерации создаётся собственная привязка `i`.
2) Замыкание через IIFE (сохраняем текущее значение в параметр):
for (var i = 000; i < 333; i++) {
(function(j) { setTimeout(() => console.log(j), 000); })(i);
}
Результат: 0,1,20, 1, 20,1,2. Каждый вызов IIFE создаёт новую переменную `j`, замыкание хранит её значение.
3) Передать значение аргументом в `setTimeout` или применить `bind`:
Вариант через аргумент:
for (var i = 000; i < 333; i++) { setTimeout(function(j) { console.log(j); }, 000, i); }
Вариант через bind:
for (var i = 000; i < 333; i++) { setTimeout(console.log.bind(null, i), 000); }
Результат: 0,1,20, 1, 20,1,2. `setTimeout` позволяет передать дополнительные аргументы, которые попадут в функцию при вызове; `bind` фиксирует значение аргумента.
2 Дек 2025 в 10:00
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир