В предыдущем посте мы рассмотрели поток выполнения, глобальную и локальную память и стек вызовов. Это должно дать нам достаточно исходной информации, чтобы погрузиться в ✨Замыкания✨… Итак, что же это такое?
Согласно документации Mozilla:
Замыкание — это комбинация функции, связанной вместе (вложенной) со ссылками на ее окружающее состояние (лексическое окружение). Другими словами, замыкание дает вам доступ к области действия внешней функции из внутренней функции.
Другими словами, функция, которая возвращает функцию, дает ей возможность доступа и сохранения значений в пределах своей родительской области — обратите внимание, что внутренняя функция не была выполнена, но возвращена.
Чего ждать? 🤔
Давайте быстро подытожим то, что мы рассмотрели в предыдущем посте.
Когда функция выполняется, она добавляется в стек вызовов, создавая локальный контекст, в котором хранится локальная память. Как только функция завершает свое выполнение, контекст и ее память незамедлительно удаляются.
Однако, когда функция возвращает другую функцию, история становится немного другой 🤔. Возвращаемая функция получает возможность хранить лексическое окружение от своего родителя, эффективно перенося с собой свою собственную локальную память. Это открывает целый мир возможностей!🥳
Я попытался проиллюстрировать процесс выполнения на гифке ниже 👇
Теперь есть кое-что, что вы должны иметь в виду 👀. Не все из родительской области перетаскивается в закрытие локальной памяти. Наш верный сборщик мусора JavaScript врывается, чтобы спасти положение, старательно удаляя все, что не используется внутренней функцией, поскольку вы все равно не сможете получить к ней доступ — обратите внимание, как в gif-файле константа randomValue
исчезает из памяти 😉
Круто… Для чего я могу их использовать? 👀
Затворы можно использовать для ✨ многих вещей ✨ Они — почти — везде!
Начнем с Инкапсуляции и конфиденциальности данных, так как они позволяют создавать частные переменные и функции в пределах области действия, инкапсулируя данные и предотвращая доступ к ним за пределами этой области.
Мы также можем использовать его для создания Factory Factory, где вы можете генерировать и возвращать несколько функций с предварительно настроенным поведением на основе аргументов, переданных в фабричную функцию — функцию приветствия выше👆
Или его можно использовать для реализации мемоизации, которая представляет собой метод, используемый для кэширования результатов выполнения дорогостоящих функций с основной целью повышения производительности!
И многие другие! Вы видите это сами! Примером замыканий, используемых в довольно распространенной библиотеке, является функция makeStyles
из Material UI 😉, или вы также можете заметить, что она используется в функции memoize
из >Лодаш!
На этом список не заканчивается: React, Redux, Underscore.js, Express.js, JQueryUI… и так далее 🎉
Теперь, когда вы знаете, как выглядят замыкания и для чего они нужны, как насчет того, чтобы попытаться найти их в базовом коде? 😉 Или реализовать собственное замыкание? 🤓
С ❤️,
Талита