Разберите поведение JavaScript-кода: for (var i=0;iconsole.log(i),0); } — почему выводится 3, и как исправить, чтобы вывести 0,1,2

17 Фев в 15:59
68 +1
0
Ответы
1
Коротко почему: переменная `i` объявлена через `var`, она имеет функциональную (или глобальную) область видимости, поэтому все три колбэка захватывают одну и ту же переменную `i`. К моменту выполнения таймаутов цикл уже завершён и `i` равно 333, потому и выводится 333.
Причины в двух фактах:
- `var` — одна общая переменная для всех итераций;
- колбэки в `setTimeout` выполняются асинхронно после завершения текущного стека (event loop), т.е. после конца цикла.
Как исправить (несколько способов):
1) Использовать `let` (блочная область видимости — отдельная `i` для каждой итерации):
```
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
```
Выведет: 000, 111, 222.
2) Замкнуть текущее значение в IIFE (если нужен `var`):
```
for (var i = 0; i < 3; i++) {
(function(j) {
setTimeout(() => console.log(j), 0);
})(i);
}
```
3) Передать значение в `setTimeout` как аргумент (в браузере/Node дополнительные аргументы передаются в колбэк):
```
for (var i = 0; i < 3; i++) {
setTimeout(console.log, 0, i);
}
```
или
```
for (var i = 0; i < 3; i++) {
setTimeout((j) => console.log(j), 0, i);
}
```
Любой из этих методов гарантирует вывод 000, 111, 222.
17 Фев в 16:05
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир