Почему в JavaScript есть замыкания?

JS имеет закрытие из-за двух вещей, которые мы получаем; function() и лексическая область видимости. Замыкания позволяют функции обращаться к переменным из объемлющей области или среды даже после того, как она покинет область, в которой она была объявлена.

Давайте продемонстрируем с кодом,

function a() {
    let one = 'one'
    return function b() {
        let two = 'two'
        return function c() {
            let three = 'three'
            return `${one} - ${two} - ${three}`
        }
    }
}

Функции a() и b() — это функции более высокого порядка, потому что они возвращают функцию, а c() — это обычная функция.

Функция высшего порядка — это просто функция, принимающая функцию в качестве параметра, или функция, возвращающая другую функцию.

Теперь, если мы запустим функцию c(),

   a()()()
=> 'one - two - three'

Как функция c() до сих пор помнит, что такое «один» и «два»? Коробка

После выполнения функции a() текущий контекст выполнения извлекается из стека, но переменная, т. е. «единица», сохраняется внутри некоторого блока с именем Closure. Таким образом, сборщик мусора не может удалить эту переменную, то же самое происходит с функцией b(). Как только функция c() вызывается и когда мы возвращаем этот оператор, переменная среда c() будет искать переменную (один, два и три), но не сможет их найти, тогда вместо глядя в глобальном масштабе, он смотрит в поле закрытия.

JS Engine будет хранить только то, на что все еще ссылается дочерняя функция. В нашем примере функции c() по-прежнему нужны «один» и «два».

Замыкания также называются лексической областью видимости. Лексический означает, где он написан, а область видимости означает, к каким переменным у нас есть доступ.

Почему закрытие выгодно?

Предположим, у нас есть какая-то тяжелая задача, например, доступ к массивному массиву.

function task(index) {
    const massArr = new Array(8000).fill('HI')
    return massArr[index]
}
task(455)
> 'HI'

ЧТО ЕСЛИ мы вызовем эту функцию n раз? Каждый раз, когда мы запускаем его, мы создаем массив, обращаемся к индексу, и когда на массив не остается ссылок, он уничтожается, он продолжает создавать и уничтожать для каждого вызова функции. Это не так эффективно, но замыкания дают нам сверхсилу эффективности памяти. Теперь с помощью замыканий мы можем один раз создать массив и держать его в памяти, чтобы постоянно к ним обращаться. Давайте посмотрим на пример,

function task() {
    const massArr = new Array(8000).fill('HI')
    return function(index) {
        return massArr[index]
    }
}
const getIndex = task();
getIndex(444)
getIndex(345)
getIndex(7999)
> 'HI'
> 'HI'
> 'HI'

Хотя на выходе нет никакой разницы, но под капотом он более эффективен. В приведенном выше коде массив «massArr» хранится внутри блока закрытия, чтобы обращаться к нему столько раз, сколько мы хотим.

Есть еще одна важная вещь, которая делает замыкания такими полезными, — это «Инкапсуляция».

СПАСИБО! Надеюсь, вам понравилось.