Дан небольшой фрагмент кода на JavaScript: function foo(arr){ for(var i=0;i

13 Янв в 12:01
11 +1
0
Ответы
1
Причина: переменная `i` объявлена через `var` — она имеет функциональную область видимости, поэтому все функции-обратного вызова захватывают одну и ту же переменную `i`. К моменту выполнения `setTimeout` цикл уже завершён и `i == arr.length`, поэтому в консоль выводится это значение (например, если `arr.length == 3`, вывод будет `3, 3, 3`). Формально: при условии цикла `i=0;i<arr.length;i++i = 0; i < arr.length; i++i=0;i<arr.length;i++` все замыкания видят одно и то же `iii`.
Варианты исправления (минимум два):
1) Использовать блочную переменную `let` в цикле (каждая итерация получает свою копию `i`):
function foo(arr){
for (let i = 0; i < arr.length; i++){
setTimeout(function(){
console.log(i);
}, 0);
}
}
2) Захватить текущее значение `i` через IIFE:
function foo(arr){
for (var i = 0; i < arr.length; i++){
(function(i){
setTimeout(function(){
console.log(i);
}, 0);
})(i);
}
}
Дополнительно (ещё два простых способа):
3) Передать значение `i` как аргумент в `setTimeout` (поддерживается в среде браузера/Node):
function foo(arr){
for (var i = 0; i < arr.length; i++){
setTimeout(function(i){
console.log(i);
}, 0, i);
}
}
4) Использовать `forEach`, где индекс — параметр функции (внутри уже блоковая область для каждого вызова):
function foo(arr){
arr.forEach(function(_, i){
setTimeout(function(){
console.log(i);
}, 0);
});
}
Любой из первых двух способов решит проблему; вариант с `let` — самый простой и читаемый.
13 Янв в 12:48
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир