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

Чтобы правильно понять замыкания, нам нужно взглянуть на области видимости в JavaScript. JS имеет две области видимости: глобальную и локальную. Глобальная область видимости указывает на переменные вне функции, а локальная область указывает на переменные внутри функции.

Так что же происходит, когда у нас есть функции внутри функции? Вот где приходит завершение.

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

Следующая функция является наиболее простым примером использования закрытия, поскольку переменные объявлены вне функции, но по-прежнему доступны для использования в функции brokenHeart. Это демонстрирует лексический объем.

Это может показаться очень очевидным, потому что пример очень простой. Но вот еще один пример, в котором у нас есть оператор if else (который считается функцией) внутри другой функции с именем useClosure:

В приведенном выше примере у нас есть два блока кода. В первом блоке переменная «feel» объявляется внутри функции useClosure, но вне оператора «if then». Во втором блоке переменная объявляется вне функции useClosure и оператора if then. Оба блока кода будут иметь доступ к переменной «ощущение» из-за лексической области видимости.

Что произойдет, если вы захотите использовать переменную под названием «чувство» в функции Y, но она объявлена ​​только в функции X, а функция X не является внешней функцией Y?

Вы получаете сообщение об ошибке, говорящее о том, что переменная «ощущение» не определена, это из-за лексической области видимости JavaScript и локальной памяти функций.

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

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

Итак, чтобы исправить приведенный выше пример, мы можем поместить функцию Y внутри функции X:

Функция Y теперь имеет доступ к переменной «чувство». Если вы используете console.dir (y), вы сможете увидеть все клавиши, доступные для этой функции:

Как вы можете видеть в ключе [[Scopes]], у нас есть еще один ключ, называемый Closure, в котором содержатся переменные, унаследованные от функции x. Мы можем добавить столько переменных, сколько захотим поместить в наш «рюкзак», используя их во внутренней функции. Любая переменная, которая не используется во внутренней функции, не помещается в наш рюкзак.

В приведенном выше примере у нас есть три переменных, доступных в функции X. Однако только две из переменных используются в функции Y, поэтому только две, которые мы используем, помещаются в наш «рюкзак». Даже после того, как внешняя функция завершила работу и ее локальная память была стерта, мы все еще можем использовать нужные нам переменные.

Ниже вы можете видеть, что ощущение переменной недоступно после завершения выполнения функции, но все еще будет доступно для использования функцией Y.

Я надеюсь, что это помогло прояснить путаницу вокруг замыканий. Хотел бы я знать это, когда только начал программировать, но лучше поздно, чем никогда. Я призываю вас поэкспериментировать с концепцией замыканий в вашей консоли. Консоль - отличный инструмент не только при создании проектов, но и при попытке выяснить, какая информация у вас есть и где.

Вот официальная документация по закрытию.