Замыкания в JavaScript
Понимание JavaScript();
Привет, JS-разработчики! Мы слышим этот сумасшедший термин «закрытие» каждый день, верно? а что, если я скажу, что мы тоже используем его очень часто?
хорошо…., Подождите, что 🙁? мы используем его ежедневно? как и где? Я знаю, что таких, как я, много, так что давайте разбираться вместе.
Никто не знает, все учатся
много вопросов, да? Итак, давайте начнем эту историю с небольшого определения закрытия.
Что такое закрытие?
согласно MDN docs
Замыкание — это комбинация функции, связанной вместе (вложенной) со ссылками на ее окружающее состояние (лексическое окружение). Другими словами, замыкание дает вам доступ к области действия внешней функции из внутренней функции. В JavaScript замыкания создаются каждый раз, когда создается функция, во время создания функции.
Проще говоря, замыкание — это функция со своим лексическим окружением.
да да, я знаю, что это все еще немного сложно понять, хорошо, давайте сделаем это проще, сначала разобравшись с областью действия.
что такое область действия?
область действия относится к области функции, в которой она может получить доступ к переменным и операторам.
printName — это функция, и функция может получить доступ ко всем операторам журнала консоли, поскольку эти операторы находятся внутри функции.
- вам может быть интересно, если age пишется за пределами области действия функции, но все же к нему обращаются в функции, как? 😕
ты нам лжешь? вы бы сказали: «Вот почему у меня проблемы с доверием 😞» - ладно ладно, расслабься, я не вру. функция может получить доступ к операторам, написанным вне функции, если эти операторы находятся внутри родительской области действия функции.
- но внешняя область не может получить доступ к переменным внутренней области, запутавшись?
- область действия может быть: локальная область действия глобальная область действия
- Глобальная область действия: означает глобальное пространство или общедоступное пространство за пределами функции.
- Локальная область: означает локальную область или ограниченную область внутри функции.
- поэтому переменная name находится внутри области действия функции printName, и если мы попытаемся получить доступ к переменной name вне области действия функции, которую она дает ошибка: Uncaught ReferenceError: имя не определено.
возвращаясь к замыканиям, функция, получающая доступ к переменным/значениям из своей родительской области (родительская функция или глобальная область), эта концепция известна как замыкание.
- принтер является родительской функцией printDetails, поэтому функция printDetails может получить доступ ко всем переменным/значениям из области своей родительской функции, и именно это и есть закрытие.
- вы, ребята, серьезно 😳, да да, я серьезно, вот что такое закрытие.
- замыкание — это функция, связанная со своим лексическим окружением.
- еще один пример закрытия.
- когда приведенная выше программа была приостановлена до строки 4, отладчик говорит, что это значение из замыкания. что это значит?
- поэтому функция b() имеет свою лексическую область видимости для своей родительской функции a(), а переменная x является частью лексической области видимости функции b().
- поэтому любая переменная, присутствующая в лексической области действия функции, может быть доступна функции.
- когда вы возвращаете функцию в js, вы не только возвращаете функцию, но и возвращаете функцию с ее лексической областью видимости.
- он запоминает лексическую область действия функции, и когда функция выполняется, она берет значения из этой лексической области.
как указано здесь, существуют вложенные функции, joinFirstAndLastNameAndAddAge — это функция, вложенная в namePrinter, а namePrinter — это снова функция, вложенная в основную функцию с именем принтер.
говоря о области действия здесь, мы видим, что самая внутренняя функция имеет все операторы (в нашем случае печатает все данные), но как она получает доступ к переменным из внешней функции?
самая внутренняя функция может получить доступ к переменным из родительской области (в нашем случае две внешние функции). Функция joinFirstAndLastNameAndAddAge может получить доступ к переменным из функции namePrinter. Но если функция namePrinter хочет получить доступ к переменным из самой внутреннейфункцииjoinFirstAndLastNameAndAddAge, так как она находится за пределами > функция joinFirstAndLastNameAndAddAge.
это магия javascript.