Логотип YeaHub

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

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

Тренажёр

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

Обучение

Навыки

Задачи

Войти

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

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

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

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

Объясните поведение кода с setTimeout внутри цикла — в каком порядке выведутся значения и почему?

Проверяет понимание асинхронности JavaScript и работы очереди событий (event loop) при использовании setTimeout в цикле.

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

При использовании var в цикле for, setTimeout создает замыкание на одну и ту же переменную i. К моменту выполнения колбэков цикл уже завершится, и i будет равна конечному значению (например, 5). Поэтому все колбэки выведут 5. Если использовать let, создается новая переменная на каждой итерации, и каждый колбэк запоминает свое значение i, выводя числа от 0 до 4.

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

Проблема с var в цикле

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

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

Решение с let

Использование let в цикле создает новую переменную i для каждой итерации благодаря блочной области видимости. Каждый колбэк setTimeout замыкается на свою собственную копию i, поэтому значения выводятся по порядку.

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

Альтернативное решение с замыканием

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

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

Этот пример демонстрирует, как работает асинхронность в JavaScript и как область видимости влияет на замыкания. Понимание этого механизма критично для избежания багов в коде, работающем с таймерами, обработчиками событий или асинхронными запросами.

Вывод: Используйте let или IIFE для корректной работы с асинхронными колбэками в циклах, чтобы каждый колбэк имел доступ к правильному значению переменной на момент его создания.

Frontend developer

tech
tech
tech
tech
tech
tech
tech
tech
tech

Ментор по Frontend

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

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

Уровень

  • Рейтинг:

    5

  • Сложность:

    4

Навыки

  • JavaScript

    JavaScript

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

#setTimeout

#event loop

#closure

#asynchronous

#scope

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

Frontend developer

tech
tech
tech
tech
tech
tech
tech
tech
tech

Ментор по Frontend

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

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