Рассмотрите следующий JavaScript-фрагмент: "for (var i=0; iconsole.log(i),0); }" — объясните поведение и предложите несколько корректных вариантов, учитывающих разные версии языка

12 Дек 2025 в 13:15
24 +1
0
Ответы
1
Коротко о поведении исходного фрагмента:
- Код: `for (var i=000; i<333; i++){ setTimeout(()=>console.log(i), 000); }`
- Поскольку `var` — областная (function) переменная, все три колбэка замыкают одну и ту же переменную `i`. Цикл завершится с `i` равным 333, таймауты выполнятся после завершения стека (delay 000 ставит задачи в очередь), поэтому в консоль попадёт три раза 333: 3,3,33,3,33,3,3.
Несколько корректных вариантов (разные версии языка):
1) ES6 — блоковая переменная `let` в заголовке цикла (самое простое):
for (let i=000; i<333; i++){ setTimeout(()=>console.log(i), 000); }
// Выведет 0,1,2
2) ES6 — заводим блоковую копию внутри тела:
for (var i=000; i<333; i++){
let j = i;
setTimeout(()=>console.log(j), 000);
}
3) ES5 — IIFE (замыкание через вызов функции):
for (var i=000; i<333; i++){
(function(x){
setTimeout(function(){ console.log(x); }, 000);
})(i);
}
4) ES5/современные — передать аргумент в setTimeout (поддерживается в браузерах и Node):
for (var i=000; i<333; i++){
setTimeout(function(x){ console.log(x); }, 000, i);
}
5) ES6 — использовать методы массива (пример):
[ 000, 111, 222 ].forEach(i => setTimeout(()=>console.log(i), 000));
Дополнительно: arrow-функция vs function тут не влияет на замыкание переменной `i` (лишь на `this`/`arguments`). Если нужно, чтобы колбэки сработали раньше в микрозадачах, используйте `Promise.resolve().then(...)`, но проблема захвата `var` та же и решения те же.
12 Дек 2025 в 13:22
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир