Проблема замыканий в JavaScript: практический пример с циклами

Привет, ребята! У меня возникла проблема с замыканиями в JavaScript, когда я использую циклы. Вот пример кода:

let functions = [];
for (var i = 0; i < 3; i++) {
  functions[i] = function() {
    console.log('Значение:', i);
  };
}
functions.forEach(f => f());

Я ожидал, что он выведет:

Значение: 0
Значение: 1
Значение: 2

Но вместо этого получаю:

Значение: 3
Значение: 3
Значение: 3

Та же проблема возникает с обработчиками событий и асинхронным кодом. Как это исправить? Я пробовал использовать let вместо var, но не уверен, что это правильное решение. Может, кто-нибудь объяснит, в чем тут дело, и как сделать так, чтобы код работал как задумано? Буду благодарен за помощь!

Дело в том, что var создает одну переменную на весь цикл. К моменту вызова функций i уже равно 3. Самое простое решение - заменить var на let. Это создаст новую переменную i для каждой итерации:

for (let i = 0; i < 3; i++) {
functions[i] = function() {
console.log(‘Значение:’, i);
};
}

Так каждая функция получит свое значение i. Это современный и правильный подход к решению такой проблемы.

эта проблема связана с особенностями var в js. когда ты использоуешь var, переменная i становится глобальной для всей функции, и к моменту вызова функций из массива она уже равна 3.

чтобы исправить, можно использовать let вместо var - это создаст блочную область видимости для i в каждой итерации цикла.

или можно использовать замыкание, создавая функцию внутри цикла:

for (var i = 0; i < 3; i++) {
functions[i] = (function(num) {
return function() {
console.log(‘значение:’, num);
};
})(i);
}

так каждая функция получит свою копию i

Да, проблема в области видимости var. Еще один способ решить - использовать метод forEach с передачей индекса:

functions = Array.from({length: 3}, (_, i) => () => console.log(‘Значение:’, i));

Так создается массив функций, каждая из которых замыкает свой индекс. Просто, эффективно и современно. Как тебе такой вариант?