Объясните поведение и исправьте ошибку в следующем JavaScript‑фрагменте: function makeArr(){ var arr = []; for (var i=0;i

6 Окт 2025 в 10:39
20 +1
0
Ответы
1

Проблема тут не в функции или в стрелках, а в области видимости переменной i. В вашем коде i объявлена через var — она имеет функциональную область видимости, поэтому все три замыкания ссылаются на одну и ту же переменную i. После завершения цикла i равно 3, и все функции возвращают это значение. Поэтому вывод будет:

3 3 3

Как это починить — варианты.

1) Самый простой (ES6+): использовать let в цикле — для каждой итерации создаётся своё блочное связывание i:

function makeArr(){
var arr = [];
for (let i = 0; i < 3; i++) {
arr.push(function(){ return i; });
}
return arr;
}
const a = makeArr();
console.log(a[0](), a[1](), a[2()]); // 0 1 2

(То же с стрелочной функцией: arr.push(() => i); — стрелок ничего не меняет в плане захвата переменных, он просто лексически связывает this.)

2) Если нужно поддерживать старый JS (без let), создать новую переменную для каждой итерации через IIFE:

function makeArr(){
var arr = [];
for (var i = 0; i < 3; i++) {
(function(j){
arr.push(function(){ return j; });
})(i);
}
return arr;
}

3) Или фабрика-функция / стрелка с немедленным вызовом:

function makeArr(){
var arr = [];
for (var i = 0; i < 3; i++) {
arr.push(((j) => () => j)(i)); // либо: arr.push((function(j){ return function(){return j} })(i));
}
return arr;
}

4) Ещё вариант — внутри тела цикла создать const j = i и замыкаться на j:

for (var i = 0; i < 3; i++) {
const j = i;
arr.push(() => j);
}

Комментарии по стрелочным функциям и const:

Заменив обычную функцию на стрелочную (function() → () => ), вы не уберёте проблему саму по себе: стрелочная функция тоже захватывает переменные лексически, поэтому при var i все стрелки вернут 3. Стрелки отличаются в первую очередь поведением this, а не семантикой замыканий переменных.const a = makeArr(); никак не влияет на содержимое массива — const запрещает переназначение переменной a, но не делает элементы массива неизменяемыми.Нельзя писать for (const i = 0; ...; i++) — const нельзя инкрементировать. Для цикла используйте let.

Вывод: проблема — общая переменная i (объявлена через var). Решение — дать каждой итерации своё связывание (let в заголовке цикла, новая переменная в теле цикла или IIFE / фабрика).

6 Окт 2025 в 11:17
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир