Замыкание представляет собой комбинацию функции и лексического окружения (scope, область видимости), в котором была объявлена эта функция. Замыкание - это фундаментальное и мощное свойство Javascript. В этой статье обсуждаются «как» и «почему» о Замыкании:
Замыкание «запоминает» окружение, в котором оно было создано. Это окружение состоит из любых локальных переменных, которые были в области видимости на момент создания Замыкания.
Замыкания полезны, потому что они позволяют вам «запоминать» данные, а затем позволяют работать с этими данными через возвращаемые функции. Это позволяет javascript эмулировать приватные методы, которые существуют на других языках программирования. Приватные методы полезны для ограничения доступа к коду, а также для управления глобальным пространством имен.
В этом примере мы не сможем получить доступ к `balance` из любой точки вне функции `bankAccount` , а это значит, что мы только что создали приватную переменную. Где закрытие? Ну, подумайте о том, что возвращает`bankAccount()` . Он фактически возвращает объект с кучей функций внутри него, и все же, когда мы вызываем `account.getBalance()` , функция может «запомнить» свою начальную ссылку на `balance` . Это сила Замыкания, когда функция «запоминает» ее лексическую область (область во время компиляции), даже если функция выполняется вне этой лексической области.
**Эмуляция блочной области видимости переменных.**
В Javascript не было концепции блочной области видимости переменных. Это означает, что при определении переменной внутри forloop, например, эта переменная видима также снаружи forloop. Итак, как могут замыкания помочь нам решить эту проблему? Давайте посмотрим.
Поскольку переменная i не имеет блочной области видимости, ее значение во всех трех функциях обновлялось с помощью счетчика циклов и создавало неожиданные значения. Замыкание может помочь нам решить эту проблему, создав снимок окружения, в котором находилась функция, когда она была создана, сохранив ее состояние.
В поздних версиях javascript es6 + есть новое ключевое слово, называемое `let` , которое может использоваться для приобретения переменной блочной области видимости. Существует также множество функций (forEach) и целых библиотек (lodash.js), предназначенных для решения таких проблем, как те, которые были описаны выше. Они, безусловно, могут повысить вашу производительность, однако крайне важно иметь знания обо всех этих проблемах при попытке создать что-то большое.
В отличие от многих других языков, Javascript не имеет механизма, который позволяет создавать инкапсулированные переменные экземпляра внутри объекта. Наличие переменных публичного экземпляра может вызвать множество проблем при построении средних и больших программ. Однако с замыканием эта проблема может быть смягчена.
Как и в предыдущем примере, вы можете создавать функции, которые возвращают литералы объектов с методами, которые имеют доступ к локальным переменным объекта, не раскрывая их. Таким образом, они становятся приватными.
Замыкание также может помочь вам управлять глобальным пространством имен, чтобы избежать коллизий с глобально доступными данными. Обычно все глобальные переменные доступны для всех скриптов в вашем проекте, что определенно создаст вам много проблем при создании средних и больших программ. Вот почему авторы библиотек и модулей используют замыкание, чтобы полностью скрыть методы и данные модуля. Это называется шаблоном модуля, он использует немедленно вызываемые функции, которые экспортируют только определенный функционал во внешний мир, что значительно сокращает количество глобальных ссылок.
Замыкание полезно для захвата новых экземпляров приватных переменных, содержащихся в «запоминаемом» окружении, и к этим переменным можно получить доступ только через возвращаемые функцию или методы.