Выбор ответа Junior Области видимости и замыкания спрашивают часто обновлено
Почему let в цикле чинит setTimeout
Вопрос
Почему for (let i = 0; i < 3; i++) setTimeout(() => console.log(i)) выводит 0 1 2, а с var выводит 3 3 3?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Правильный ответ: let даёт новую привязку i на каждую итерацию, а var одна на функцию. Спецификация для for с let создаёт отдельное окружение на каждую итерацию и копирует туда текущее значение счётчика.
Варианты ответа
letдаёт новую привязкуiна каждую итерацию, аvarодна на функциюправильный ответ- С
letколбэкиsetTimeoutвнутри цикла выполняются синхронно, сразу letкопирует значение в колбэк при вызовеsetTimeout, аvarпередаёт ссылку- С
varтаймеры срабатывают в обратном порядке, и выводится последнее значение
Разбор
Спецификация для for с let создаёт отдельное окружение на каждую итерацию и копирует туда текущее значение счётчика. Каждая стрелка замыкает свою i. С var переменная одна, к запуску колбэков цикл закончился и она равна 3. Колбэки таймеров асинхронны в обоих случаях. «Копирование значения в колбэк» неверно: замыкание всегда хранит ссылку на переменную, просто с let переменных три. Порядок таймеров с одинаковой задержкой сохраняется.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.