Важная концепция, объясненная на понятных и простых примерах

Основы JavaScript - это серия статей, в которых исследуются некоторые основные концепции, которые должен понимать каждый разработчик внешнего программного обеспечения. Эти концепции важны не только для успеха на собеседовании, но и для карьеры разработчика.

В этом разделе нашей серии статей по основам JavaScript мы объясним очень важную концепцию, известную как закрытие. Что делает особенно важным то, что это не только основная концепция самого JavaScript, но и очень вероятно, что она будет затронута во время собеседований, связанных с JavaScript. Давайте без лишних слов перейдем к делу! 😃

Что такое закрытие?

Одно из лучших определений этого слова содержится в веб-документации Mozilla:

Замыкание - это комбинация функции, объединенной (заключенной) со ссылками на ее окружающее состояние (лексическое окружение). Другими словами, замыкание дает вам доступ к области внешней функции из внутренней функции. В JavaScript замыкания создаются каждый раз, когда создается функция, во время создания функции.

Другими словами, это факт помещения функции внутри другой, что дает закрытой функции доступ к внешним переменным. Термин «лексическая среда» в данном случае относится к объему внешней функции. Давайте проиллюстрируем это на примере:

function outer(){
     let outerVar = "outside";
     function inner(){
            let innerVar = "inside";
            console.log("The outer variable is " + outerVar);
     }
 return inner;
}

Выход: [Function: inner]

В JavaScript любая выполняемая функция по умолчанию создает закрытие

Внутренняя функция имеет доступ к переменной внешней функции, поскольку она находится в пределах ее локальной или лексической области видимости. В частности, я хотел бы отметить следующие моменты:

  • Внутренняя часть имеет доступ к переменной внешней функции, тогда как последняя не имеет доступа к innerVar. Лексическая область видимости - это улица с односторонним движением, только внутренняя функция может получить доступ к чему-либо во внешней функции.
  • Внешняя функция может получать результаты (возвращаемое значение, вывод в консоль и т. Д.) Только внутренней функцией, возвращая ее.
  • Возвращается только определение функции, но не вызов! Внутренняя функция не вызывается.
  • Внутренняя функция возвращается из внешней функции перед выполнением.

Это означает, что технически он не должен иметь доступа к переменным внешней функции. Во многих языках программирования все переменные внешней функции были бы объявлены и продолжали существовать до момента, когда функция вернет значение (в данном случае внутренняя функция). Когда функция вызывается, она создает стек вызова (или выполнения), который представляет собой просто специализированное выделенное пространство памяти. Каждый вызов создает свой собственный стек выполнения с набором локальных переменных. Например, в традиционных языках, таких как C / C ++, при вызове внутренней функции создается собственный стек памяти (см. Диаграмму ниже). Следовательно, внутренняя функция не будет иметь доступа к каким-либо переменным вне ее собственной области действия. Однако в JavaScript каждая выполняемая функция создает закрытие. Другими словами, каждая функция создается с возможностью заключать функции внутри себя, это вложение дает их внутренним функциям доступ ко всем переменным внутри них. Следовательно, замыкание - это просто комбинация функции и ее лексической области видимости.

Теперь предположим, что мы хотим вернуть фактическое значение внутри второй функции, а не ее определение. Для этого мы могли бы добавить следующие строки кода:

let innerOutput = outer();  //Output: [Function: inner]
/*
 Here's what happens behind the scenes after the code above runs:
 innerOutput = inner
*/
console.log(innerOutput())
//Same as innerOutput = inner();

Выход: The outer variable is outside

Что делает закрытие таким важным, так это то, что оно сохраняет внутренние переменные закрытыми. Ничто вне вложенной функции не может получить доступ к ее переменным. Это важно при использовании обработчиков событий, частичных приложений и функций обратного вызова. Цель состоит в том, чтобы упростить задачу, поэтому мы можем рассказать об этих концепциях в другом блоге.

А пока мы можем резюмировать вышесказанное следующим образом:

  • Замыкание - это факт включения функции в другую, так что вложенная функция может обращаться к переменным за пределами своей собственной области видимости.
  • Для каждой создаваемой функции JavaScript по умолчанию создает закрытие.
  • Замыкания обеспечивают конфиденциальность переменных вложенной функции.

Спасибо за чтение! Удачного кодирования! 😃