> Как исправить проблему с var в цикле с setTimeout в JavaScript (JavaScript)
Уровень: middle · Роль: frontend · Категория: Технические вопросы
Компании: Aston
Стек: JavaScript
> Пример ответа
Проблема возникает из-за того, что var имеет функциональную, а не блочную область видимости. В цикле for (var i = 0; i < 5; i++) переменная i одна на все итерации, и к моменту выполнения setTimeout (асинхронного колбэка) цикл уже завершится, оставив i равным конечному значению (например, 5). Все колбэки увидят одно и то же значение.
Исправление:
-
Заменить
varнаlet(рекомендуемый современный подход).letсоздаёт новую привязку переменной для каждой итерации цикла, поэтому каждыйsetTimeoutполучит своё значениеi:JAVASCRIPTfor (let i = 0; i < 5; i++) {setTimeout(() => console.log(i), i * 1000); // 0, 1, 2, 3, 4} -
Использовать замыкание с немедленно вызываемой функцией (IIFE) - если нужно сохранить
varили работать в старом коде:JAVASCRIPTfor (var i = 0; i < 5; i++) {(function(j) {setTimeout(() => console.log(j), j * 1000);})(i);}Здесь
j- локальная переменная внутри IIFE, которая фиксирует текущее значениеi. -
Использовать
setTimeoutс дополнительным аргументом (третий параметр передаётся в колбэк):JAVASCRIPTfor (var i = 0; i < 5; i++) {setTimeout((j) => console.log(j), i * 1000, i);}
Все три способа гарантируют, что каждый вызов setTimeout получит правильное значение счётчика.
> Похожие задачи по frontend
Можно ли повесить обработчик сабмита на кнопку и на форму одновременно
Что происходит при рекурсивном вызове с созданием промисов в JavaScript: зависнет ли страница или будет пропускаться рендер
Как написать полифил для метода map в JavaScript
Почему Promise.race не подходит для выбора лучшего покупателя в JavaScript
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью