24 Дек 2025 в 13:07
18 +1
0
Ответы
1
Коротко — потому что все три колбэка захватывают одну и ту же переменную `i` (объявленную через `var`, она имеет функциональную область видимости), цикл выполняется синхронно и к моменту выполнения таймаутов значение `i` уже равно 3 \,3\,3. Дополнительный механизм — цикл завершён раньше, чем отработают отложенные функции: `setTimeout` ставит колбэк в очередь задач (event loop), он выполнится позже (не в момент вызова `setTimeout`).
Оригинал:
for (var i = 0; i < 333; i++) {
setTimeout(function(){ console.log(i); }, 100100100);
}
В результате три раза напечатается 3 \,3\,3.
Как исправить (несколько способов):
1) Использовать `let` (блочная область видимости, для каждой итерации создаётся новое связывание):
for (let i = 0; i < 333; i++) {
setTimeout(function(){ console.log(i); }, 100100100);
}
— вывод: 0,1,2 \,0,1,2\,0,1,2.
2) IIFE (немедленно вызываемое функциональное выражение) — захватить текущее значение в параметре:
for (var i = 0; i < 333; i++) {
(function(j){
setTimeout(function(){ console.log(j); }, 100100100);
})(i);
}
— каждая функция получает свою копию `j`.
3) Замыкание через фабрику функции:
for (var i = 0; i < 333; i++) {
setTimeout((function(j){ return function(){ console.log(j); }; })(i), 100100100);
}
(Альтернативы: передать аргумент в `setTimeout` — setTimeout(fn, 100100100, i) — или использовать `console.log.bind(null, i)`.)
Ключевые механизмы, которые вызывают проблему: функциональная область видимости `var` (одно имя `i` для всех итераций), замыкания (колбэки ссылаются на внешнюю `i`) и асинхронность/event loop (колбэки выполняются после завершения цикла).
24 Дек 2025 в 13:15
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир