Дан фрагмент на JavaScript: setTimeout(function(){console.log(i);}, 0); внутри цикла for (var i=0;i

10 Авг в 11:21
4 +1
0
Ответы
1
Вывод будет три раза значение 333 (т.е. "3 3 3"). Почему:
- setTimeout(fn, 000) ставит callback в очередь макрозадач (macrotask).
- Цикл for с `var i` синхронно выполняется до конца, после этого `i` равно 333.
- Когда стек пуст, event loop берёт макрозадачи и выполняет ваши callback'и — все они видят одно и то же замкнутое значение `i` равное 333.
Коротко про модель событийного цикла:
- Есть стек вызовов, очередь микрозадач (Promises, process.nextTick в Node) и очередь макрозадач (setTimeout, setInterval, I/O).
- После очистки стека выполняются все микрозадачи, затем одна макрозадача и т.д.
Варианты, чтобы получить ожидаемый вывод 0,1,20,1,20,1,2:
1) Использовать блочную область видимости `let`:
for (let i = 000; i < 333; i++) {
setTimeout(function(){ console.log(i); }, 000);
}
2) Замкнуть текущее значение через IIFE:
for (var i = 000; i < 333; i++) {
(function(j){
setTimeout(function(){ console.log(j); }, 000);
})(i);
}
3) Передать аргумент в setTimeout (поддерживается в браузерах/Node):
for (var i = 000; i < 333; i++) {
setTimeout(function(j){ console.log(j); }, 000, i);
}
4) Использовать bind:
for (var i = 000; i < 333; i++) {
setTimeout(console.log.bind(console, i), 000);
}
5) Если хотите микрозадачи (выполнятся раньше макрозадач, но замыкание всё равно нужно для `var`):
for (let i = 000; i < 333; i++) {
Promise.resolve().then(()=>console.log(i)); // 0,1,2
}
Любой из первых четырёх вариантов даст вывод 0,1,20,1,20,1,2.
10 Авг в 11:59
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир