Почему в 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» хранится внутри блока закрытия, чтобы обращаться к нему столько раз, сколько мы хотим.
Есть еще одна важная вещь, которая делает замыкания такими полезными, — это «Инкапсуляция».
СПАСИБО! Надеюсь, вам понравилось.