Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Задачи

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про JavaScript: closure, setTimeout, event loop, var, scope

Почему в JavaScript при использовании setTimeout может выводиться одно и то же значение переменной на каждой итерации?

Проверяет понимание замыканий и асинхронности в JavaScript, объясняя, почему setTimeout в цикле выводит одно и то же значение.

Короткий ответ

Проблема возникает из-за использования var, которая имеет функциональную, а не блочную область видимости. Все колбэки setTimeout ссылаются на одну и ту же переменную i, которая к моменту их выполнения уже равна конечному значению цикла. Решение — использовать let для блочной области видимости или обернуть вызов в замыкание.

Длинный ответ

Почему setTimeout выводит одно и то же значение?

В JavaScript при использовании var в цикле for переменная i имеет функциональную область видимости, а не блочную. Это означает, что все итерации цикла используют одну и ту же переменную i. Когда колбэки setTimeout выполняются (после завершения цикла), значение i уже равно конечному значению (например, 3 или 10).

Пример проблемы

for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}
// Вывод: 3, 3, 3

Здесь все три колбэка выводят 3, потому что к моменту их вызова цикл уже завершился, и i равна 3.

Как это исправить?

  • Использовать let: let создаёт новую переменную для каждой итерации цикла (блочная область видимости).
  • Замыкание через IIFE: обернуть вызов setTimeout в немедленно вызываемую функцию, передавая текущее значение i как аргумент.

Пример с let

for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}
// Вывод: 0, 1, 2

Пример с замыканием

for (var i = 0; i < 3; i++) {
  (function(j) {
    setTimeout(() => console.log(j), 100);
  })(i);
}
// Вывод: 0, 1, 2

Вывод

Понимание области видимости и замыканий критично для работы с асинхронным кодом в JavaScript. Используйте let или замыкания, чтобы избежать подобных ошибок в циклах с асинхронными операциями.

Frontend developer

tech
tech
tech
tech
tech
tech
tech
tech
tech

Ментор по Frontend

Полное сопровождение до оффера — без дорогих курсов, с оплатой после трудоустройства

Записаться на консультацию

Уровень

  • Рейтинг:

    5

  • Сложность:

    4

Навыки

  • JavaScript

    JavaScript

Ключевые слова

#closure

#setTimeout

#event loop

#var

#scope

Подпишись на React Developer в телеграм

Frontend developer

tech
tech
tech
tech
tech
tech
tech
tech
tech

Ментор по Frontend

Полное сопровождение до оффера — без дорогих курсов, с оплатой после трудоустройства

Записаться на консультацию