Важно понимать, как работает внутренняя система, когда мы, как разработчик, что-то пишем. Это понимание того, как движок JS интерпретирует и запускает код, помогает разработчику писать более эффективный, оптимизированный и структурированный код.

Итак, сегодня позвольте мне поделиться своим пониманием того, что этот дракон называет «лексическим окружением» и «замыканием» в JavaScript.

Лексическое окружение

Всякий раз, когда JS-движок выполняет какую-либо функцию или, что более ценно, любой блок кода, он поддерживает некоторые данные внутри структурированным образом. Эта информация, поддерживаемая движком JS, известна как лексическая среда.

Лексическая среда в основном поддерживает 2 компонента:

  1. Запись среды: объект, в котором хранятся все локальные переменные и функции, объявленные в текущем блоке кода, как его свойства (а также значение this).
  2. Ссылка на внешнее окружение:указатель на родительское лексическое окружение, связанное с внешним кодом.

Новое лексическое окружение создается каждый раз, когда выполняется блок функции/кода. Давайте разберемся на примере.

Выполнение вышеуказанной функции происходит, как показано ниже:

Родительская функция Лексическое окружение:

  1. Когда функция «Родитель» запускается, в начале вызова создается новое лексическое окружение.
  2. По мере выполнения функции запись среды будет содержать информацию о локальной переменной и функции, поэтому в нашем примере, когда будет выполняться родительская функция, ее запись среды будет иметь функции «greet» и «child» в качестве свойств.
  3. Второй компонент лексического окружения (ссылка на внешнее окружение) здесь указывает на глобальноелексическое окружение, которое связано со всем сценарием.
  4. наша функция возвращает «дочернюю» функцию в качестве возвращаемого значения.

Дочерняя функция Лексическое окружение:

  1. При выполнении «дочерней» функции снова создается новое лексическое окружение. (назовем это внутренней лексической средой)
  2. Запись среды дочерней функции будет иметь «имя» в качестве свойств (это локальная переменная).
  3. Лексическое окружение дочерней функции будет иметь ссылку на лексическое окружение «родительской» функции (второй компонент лексического окружения, назовем его внешним лексическим окружением)
  4. Поэтому, когда выполняется дочерняя функция, даже если переменная «greet» не определена в дочерней функции, а родительская функция уже выполнена, пользователь все равно увидит «Hello World!!!». в журнале, потому что когда код хочет получить доступ к переменной — сначала просматривается внутреннее лексическое окружение, затем внешнее, затем более внешнее и так далее до глобального.

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

Закрытие

Замыкание — это комбинация функции, связанной вместе (вложенной) со ссылками на ее окружающее состояние (лексическое окружение).

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

Преимущества закрытия:

  • Сохранение состояния: здесь будет сохранено состояние переменной из-за закрытия.

  • Инкапсуляция: мы можем создавать частные методы и переменные, используя замыкание.

  • Частичные функции: мы можем создавать частичные функции с помощью замыкания.

В основном закрытие помогает и облегчает нашу работу везде, от вложенных функций до обработки событий и асинхронного программирования. Все программисты JavaScript полагались на эту функцию (просто мы этого не осознаем :D).