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

19 Янв в 12:52
29 +1
0
Ответы
1
Результат с var
- Код:
for (var i=0;iconsole.log(i),0); }
- Объяснение (коротко): цикл выполняется синхронно, все три колбэка ставятся в очередь, а переменная iii — одна общая (function-scoped). Когда колбэки выполняются, цикл уже завершён и iii равно 333. В консоль попадут: 3,3,33,3,33,3,3.
- Причина: замыкания захватывают ссылку на одну и ту же переменную iii, а не её значение в момент итерации.
Поведение с let
- Если заменить на:
for (let i=0;iconsole.log(i),0); }
- Тогда для каждой итерации создаётся своё блочное связывание iii, замыкание захватит текущее значение. Вывод: 0,1,20,1,20,1,2.
Альтернативы для сохранения ожидаемого индексного значения (вывод 0,1,20,1,20,1,2)
1) Использовать let (как выше).
2) IIFE (замыкание с параметром):
for (var i=0;i<3;i++){
(function(j){ setTimeout(()=>console.log(j),0); })(i);
}
3) Передать аргумент в setTimeout:
for (var i=0;i<3;i++){
setTimeout((j)=>console.log(j),0,i);
}
(или в браузере: setTimeout(console.log,0,i))
4) bind:
for (var i=0;i<3;i++){
setTimeout(console.log.bind(null,i),0);
}
5) Итерация по массиву:
[0,1,2].forEach(i => setTimeout(()=>console.log(i),0));
Коротко о setTimeout(..., 0): задержка 000 значит отложенный вызов в следующем макротаске — колбэки выполнятся после завершения текущего кода (поэтому значение iii уже изменится).
19 Янв в 12:58
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир