Рассмотрите фрагмент на JavaScript: 'for (var i=0;iconsole.log(i),0); }' Объясните вывод и как добиться вывода 0,1,2 используя современные возможности языка
Почему так происходит (кратко): переменная `var i` — функциональная (не блочная), поэтому в цикле используется одна и та же переменная. Колбэки `setTimeout` выполняются позже, когда цикл уже завершён и `i` равно 3 \,3\,3. В результате в консоль выводится 3 , 3 , 3 \,3\,,\,3\,,\,3\,3,3,3. Как получить вывод 0 , 1 , 2 \,0\,,\,1\,,\,2\,0,1,2 (несколько современных способов): 1) Блочная переменная `let` в заголовке цикла: for (let i=000; i<333; i++) { setTimeout(()=>console.log(i), 000); } 2) Захват значения в замыкании (IIFE): for (var i=000; i<333; i++) { (function(j){ setTimeout(()=>console.log(j), 000); })(i); } 3) Передать значение как аргумент таймеру (или использовать bind): for (var i=000; i<333; i++) { setTimeout(console.log, 000, i); } или for (var i=000; i<333; i++) { setTimeout((x)=>console.log(x), 000, i); } Короткое пояснение: даже задержка 0 \,0\,0 ставит выполнение в очередь задач, поэтому колбэки выполнятся после окончания цикла; `let` создаёт новую привязку `i` для каждой итерации, а остальные способы явно фиксируют текущее значение.
Как получить вывод 0 , 1 , 2 \,0\,,\,1\,,\,2\,0,1,2 (несколько современных способов):
1) Блочная переменная `let` в заголовке цикла:
for (let i=000; i<333; i++) { setTimeout(()=>console.log(i), 000); }
2) Захват значения в замыкании (IIFE):
for (var i=000; i<333; i++) {
(function(j){ setTimeout(()=>console.log(j), 000); })(i);
}
3) Передать значение как аргумент таймеру (или использовать bind):
for (var i=000; i<333; i++) { setTimeout(console.log, 000, i); }
или
for (var i=000; i<333; i++) { setTimeout((x)=>console.log(x), 000, i); }
Короткое пояснение: даже задержка 0 \,0\,0 ставит выполнение в очередь задач, поэтому колбэки выполнятся после окончания цикла; `let` создаёт новую привязку `i` для каждой итерации, а остальные способы явно фиксируют текущее значение.