Что это такое, как они работают и простой пример кода

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

Больше ни слова! Выкрикните слово «Закрытие» так громко, как только сможете.

Замыкание дает нам возможность хранить дополнительные функции и переменные вокруг наших функций.

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

Эта внешняя функция вокруг нашей функции действует как замыкание.

function wrapper() { 
  let counter = 0;
  function innerFunction() {
      counter ++;
      console.log (counter);
  }
  return innerFunction; 
}

Шаги для создания замыкания, как мы видим в приведенном выше коде, следующие:

  • Поместите функцию-оболочку вокруг вашей функции
  • Добавьте переменные внутри вашей функции-оболочки
  • Верните свою функцию в конце, чтобы мы могли использовать ее позже

Чтобы использовать замыкание, вы вызываете функцию-оболочку, которая возвращает только внутреннюю функцию. У вас нет доступа к счетчику. Но внутренняя функция всегда будет иметь к нему доступ.

let closure = wrapper(); 
closure(); // output: 1

В рамках этого закрытия применяются следующие правила:

  • Наша функция, которая была объявлена ​​внутри функции-оболочки, имеет доступ ко всем переменным и функциям, объявленным внутри функции-оболочки.
  • Наша функция, которая была объявлена ​​внутри обертки, всегда будет иметь доступ ко всем переменным и функциям, объявленным внутри функции-оболочки.
  • Значение этих переменных будет сохраняться при многократном выполнении функции. Это означает, что функция может многократно увеличивать данные и запоминать свои предыдущие значения.

Давайте посмотрим на другой пример кода.

Примечание. Вы можете объявлять переменные и функции, которые не возвращаются в остальную часть кода. Это сохранит их для частного использования.

function wrapper() {
  let memory = 0;
  function privateFunction() {
     return "I keep my memories";
   }
  function innerFunction () {
    memory ++;
    console.log (privateFunction(), memory);
  }
  return  { innerFunction }; // note: we only return innerFunction    here, not privateFunction
}
let closure = wrapper();
closure.innerFunction(); // output: I keep my memories 1
closure.innerFunction(); // output: I keep my memories 2
closure.innerFunction(); // output: I keep my memories 3
closure.privateFunction(); // Not able to access it!!! Private

Итак, каковы преимущества замыканий?

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

А-а... А как насчет недостатков?

  • Утечки памяти, как видите, функция всегда отслеживает свои предыдущие вызовы и состояние/переменные.