Введение
Одна из самых важных концепций в Javascript для понимания — замыкания. Это связано с тем, что понимание того, как работают замыкания, позволяет нам писать более качественные и эффективные программы. Также очень часто задают вопросы о замыканиях во время собеседований по интерфейсу и Javascript.
В этой статье мы рассмотрим, что такое замыкания, почему они важны и как ими воспользоваться.
Лексическое окружение
Чтобы понять замыкания, нам сначала нужно понять, что такое лексическая среда, потому что она формирует базовый механизм работы замыканий.
Лексическая среда — это структура данных, которая содержит сопоставление переменных в области видимости. Он создается во время создания функции и также называется записью среды. Он содержит два компонента:
- Запись среды: структура данных, содержащая карту переменных и их текущих значений в функции.
- Ссылка на лексическое окружение непосредственной внешней области видимости (родительская функция или глобальная).
Поняв вышеизложенное, давайте перейдем к определению того, что такое замыкание.
Что такое закрытие
Замыкание — это комбинация функции, связанной вместе со ссылкой на ее лексическое окружение. Он также предоставляет механизм, с помощью которого значения переменных разрешаются в функции, используя лексическое окружение функции.
Замыкания создаются каждый раз при вызове функции и активны только во время выполнения этого вызова функции. (К этому есть оговорка, как мы увидим ниже)
Как работают замыкания:
Теоретическое понимание того, как замыкания работают, может немного сбивать с толку, поэтому давайте взглянем на приведенный ниже пример кода, чтобы объяснить, как это работает.
Мы рассмотрим выполнение кода и объяснения по шагам.
После разбора скрипта движок javascript начнет выполнять код построчно. Первая операция заключается в запуске функции makeCounter() и присвоении возвращенного элемента counter.
При выполнении вызова makeCounter() механизм создаст замыкание для хранения переменных и ссылок для внутренних функций.
В этот момент значение count равно 0, и возвращается ссылка на increaseCounter(). Возвращаемая ссылка назначается счетчику.
Замыкание для функции makeCounter() по-прежнему доступно в памяти, хотя функция makeCounter() уже завершила выполнение. Это связано с тем, что на замыкание по-прежнему ссылается переменная счетчика. Движок будет поддерживать замыкание, чтобы иметь доступ к переменной count при выполнении функции counter().
Во второй строке выполняется вызов функции counter(). В этом вызове движок получает переменную count из внешней области видимости, увеличивает ее на 1 и возвращает обновленное значение. Он может сделать это, даже если в нем не определен count, потому что его закрытие имеет ссылку на внешнюю область видимости.
Замыкания разрешают переменные в следующем порядке:
- Переменные, объявленные в своей области видимости
- Переменные, объявленные в области видимости внешней функции
- Переменные, объявленные в глобальной области видимости
Это означает, что при разрешении значения для переменной область функций сначала ищется, если переменная не определена там, движок перемещается вверх и проверяет родительскую функцию, и если она не найдена там, она затем перемещается вверх к области видимости. глобальный охват. В приведенном выше коде переменная находится в родительской функции.
На данный момент значение count равно 1.
Следующая строка кода снова запускает вызов функции counter(). Выполняет то же действие, что и предыдущая операция. В конце скрипта значение count равно 2.
Примеры использования Closures в реальном мире
Давайте взглянем на некоторые примеры использования замыканий в реальном мире.
Частные переменные
Мы можем создавать приватные переменные, которые можно безопасно обновлять, как в приведенном выше коде. Функция driveCar() возвращает только методы для получения или обновления значения скорости, но не саму скорость. Таким образом, никакая часть нашего кода не может установить скорость на › 70, потому что у нас есть защита от этого.
Кэширование
Мы можем создать функцию, которая вычисляет только один раз и извлекает из кеша, если мы передаем те же аргументы для следующих вызовов. Это полезно, потому что нам нужно выполнить тяжелые операции только один раз, а затем полагаться на кеш для последовательных вызовов этой операции.
Декораторы
Мы можем использовать замыкания при написании некоторых функций-декораторов. Декораторы — это функции, которые принимают и возвращают модифицированную версию функции. Вместо использования IIFE для создания решения для кэширования, описанного выше, мы можем создать декоратор кэша, который позволит нам добавить кэширование к любой функции. Давайте посмотрим код для этого ниже.
Заключение
Мы рассмотрели, что такое замыкания, почему они важны и как использовать их преимущества в Javascript. Мы также рассмотрели некоторые примеры использования замыканий в реальном мире.
Обладая этими знаниями, мы теперь можем писать более качественный и эффективный код javascript. Мы также можем воспользоваться тем фактом, что javascript является функциональным языком программирования, и использовать замыкания для написания более функционального кода.
Я надеюсь, что вы нашли эту статью полезной. Пожалуйста, оставьте комментарий ниже, если у вас есть какие-либо вопросы или предложения.