Разберите тонкость замыканий в JavaScript: var funcs=[]; for(var i=0;i

19 Сен в 04:12
2 +2
0
Ответы
1
Потому что замыкание в JavaScript захватывает саму переменную, а не её значение в момент создания функции. В вашем коде `var` даёт одну общую переменную `i` для всего цикла; после выхода из цикла `i` становится 333, и все сохранённые функции при вызове читают текущее значение переменной — поэтому `funcs[0]()` выведет 333.
Как сохранить текущее значение `i` для каждой функции (несколько способов):
1) Использовать `let` (блочная область видимости — для каждой итерации своя `i`):
```js
var funcs = [];
for (let i = 0; i < 3; i++) {
funcs.push(function(){ console.log(i); });
}
funcs[0](); // 0
```
2) Замыкание через IIFE (функция немедленно вызывается и получает копию `i`):
```js
var funcs = [];
for (var i = 0; i < 3; i++) {
(function(j){
funcs.push(function(){ console.log(j); });
})(i);
}
funcs[0](); // 0
```
3) Фабрика функций (передаём `i` как параметр и возвращаем функцию):
```js
function makeLogger(j) {
return function(){ console.log(j); };
}
var funcs = [];
for (var i = 0; i < 3; i++) {
funcs.push(makeLogger(i));
}
funcs[0](); // 0
```
4) Использовать `bind` для привязки аргумента:
```js
var funcs = [];
for (var i = 0; i < 3; i++) {
funcs.push(console.log.bind(null, i));
}
funcs[0](); // 0
```
Итого: причина — одна общая `var`-переменная и замыкание на неё; решение — дать каждой итерации отдельную переменную/копию значения (через `let`, IIFE, фабрику или `bind`).
19 Сен в 04:18
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир