Найдите и объясните проблему в JavaScript-коде: "for (var i = 0; i console.log(i), 100);" — как исправить, если нужно вывести 0, 1, 2, и какие механизмы языка здесь ответственны за поведение?

26 Янв в 12:23
11 +1
0
Ответы
1
Проблема: колбэки замыкают одну переменную `var i` (функциональная область видимости). Цикл `for (var i = 0; i < 3; i++)` успевает закончиться до срабатывания таймаутов, поэтому в момент выполнения `console.log(i)` значение `i` равно `3`. В итоге вывод будет 3,3,33,3,33,3,3, а не 0,1,20,1,20,1,2.
Механизмы языка, ответственные за поведение:
- var — функциональная (не блочная) область видимости: одна общая переменная `i` для всех итераций.
- Замыкания: колбэки получают доступ к той же самой переменной `i`, а не к её копии.
- Event loop / макротаски: `setTimeout` выполняет колбэк позже, после завершения цикла.
- В ES6 `let` даёт пер-итерационный binding: для каждой итерации создаётся своё блочное привязывание `i`.
Как исправить (несколько вариантов):
1) Использовать `let` в заголовке цикла (самый простой современный способ):
for (let i = 0; i console.log(i), 100);
2) Замкнуть текущее значение через IIFE:
for (var i = 0; i console.log(x), 100); })(i);
3) Передать значение как аргумент таймауту (поддерживается в браузерах и Node):
for (var i = 0; i console.log(x), 100, i);
4) Использовать bind для привязки аргумента:
for (var i = 0; i < 3; i++) setTimeout(console.log.bind(null, i), 100);
Любой из этих способов даст ожидаемый вывод 0,1,20,1,20,1,2.
26 Янв в 12:29
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир