Замыкания позволяют программистам JavaScript писать более качественный код. Креативно, выразительно и лаконично. Мы часто используем замыкания в JavaScript, и, независимо от вашего опыта работы с JavaScript, вы, несомненно, будете сталкиваться с ними снова и снова. Конечно, замыкания могут показаться сложными и выходящими за рамки вашей компетенции, но после того, как вы прочитаете эту статью, замыкания станут намного более понятными и, следовательно, более привлекательными для ваших повседневных задач программирования на JavaScript.

Что такое закрытие?

Замыкание – это комбинация функции, объединенной (вложенной) со ссылками на ее окружающее состояние (лексическое окружение). Другими словами, замыкание дает вам доступ к области действия внешней функции из внутренней функции. В JavaScript замыкания создаются каждый раз, когда создается функция, во время создания функции.

Лексическая область видимости
Лексическая область видимости в JavaScript означает, что переменная, определенная вне функции, может быть доступна внутри другой функции, определенной после объявления переменной. Но обратное неверно; переменные, определенные внутри функции, не будут доступны вне этой функции.

Рассмотрим следующий пример кода:

init() создает локальную переменную с именем name и функцию с именем displayName(). Функция displayName() — это внутренняя функция, определенная внутри init() и доступная только в теле функции init(). Обратите внимание, что функция displayName() не имеет собственных локальных переменных. Однако, поскольку внутренние функции имеют доступ к переменным внешних функций, displayName() может получить доступ к переменной name, объявленной в родительской функции init().

Правила закрытия и побочные эффекты

1. Замыкания имеют доступ к переменной внешней функции даже после возврата внешней функции:

Одной из наиболее важных и щекотливых особенностей замыканий является то, что внутренняя функция по-прежнему имеет доступ к переменным внешней функции даже после возврата внешней функции. Да, вы правильно прочитали. Когда функции в JavaScript выполняются, они используют ту же цепочку областей видимости, которая действовала при их создании. Это означает, что даже после возврата внешней функции внутренняя функция по-прежнему имеет доступ к переменным внешней функции. Поэтому вы можете вызвать внутреннюю функцию позже в своей программе. Этот пример демонстрирует:

2. Замыкания хранят ссылки на переменные внешней функции;

Они не сохраняют фактическое значение. Замыкания становятся более интересными, когда значение переменной внешней функции изменяется до вызова замыкания. И эту мощную функцию можно использовать творчески, например, в этом примере с частными переменными, впервые продемонстрированном Дугласом Крокфордом:

3. Замыкания пошли наперекосяк

Поскольку замыкания имеют доступ к обновленным значениям переменных внешней функции, они также могут привести к ошибкам, когда переменная внешней функции изменяется с помощью цикла for. Таким образом, чтобы исправить этот побочный эффект (ошибку) в замыканиях, вы можете использовать ES6 Feature let в for loop.

Просто помните, что застежки — это аналогия с рюкзаком. Когда функция создается и передается или возвращается из другой функции, она несет с собой рюкзак. А в рюкзаке лежат все переменные, которые были в области видимости при объявлении функции.