Замыкание и области видимости
Создать функцию, возвращающую массив функций, возвращающих свой индекс в массиве.
Объясните, как это сделать. Что-то совсем непонятна тема с замыканиями.
Ответы (1 шт):
Автор решения: Alexander Lonberg
→ Ссылка
Так как из массива могут вырезать данные, искать надо именно по ссылке на саму функцию - текущий индекс, а не индекс на момент создания.
Это не самое удачное задание, для объяснений с замыканиями, но комменты оставлю.
function arrayOfIndexesReturn(num = 10) {
let arrayOfIndexes = []
for (let i = 0; i < num; i++) {
// Внутри цикла(и не только) можно определить временную переменную, ЖИВУЩУЮ РОВНО ОДНУ ИТЕРАЦИЮ.
// let fun <- ВОТ ОНА
// НО, если кто-то(А) получит на нее ссылку и этот А не собирается "самоуничтожиться",
// переменная будет доступна на протяжении всей жизни А и только для него.
// Вот этим А и является функция - как видим fun используется аргументом в .indexOf(fun).
// При этом никто не запрещает инициализировать нашу переменную fun этой самой функцией.
let fun = () => ({ current: arrayOfIndexes.indexOf(fun), created: i})
arrayOfIndexes.push(fun)
// В этот самый момент, когда мы собирались покинуть итерацию и распрощаться
// с временной переменной fun, и произошло это самое ЗАМЫКАНИЕ.
// JavaScript сообразил: - Ведь кто-то воспользуется этой самой функцией, а значит будет
// нужна ссылка на fun. И сохранил лексическое окружение созданное на момент итерации.
}
return arrayOfIndexes
}
const arr = arrayOfIndexesReturn()
console.log(arr[5]())
arr.splice(0, 1)
// Реально это 7-ая добавленная функция, но после удаления,
// и благодаря замыканию, она найдет текущий индекс
console.log(arr[5]())
Лучше, конечно, разбирать ЗАМЫКАНИЯ на задачах типа счетчиков
const counter = ((n = 0) => {
return () => ++n
})()
counter() // 1
counter() // 2