Используем замыкания на полную

Если вы слышите слово "замыкание" впервые, оно может заставить вас нервничать. Но не стоит волноваться. На самом деле, замыкание - это просто. Для того, чтобы понять, как работает замыкание, необходимо вспомнить, что является областью видимости в Javascript. Вопрос с подвохом, так как для ключевого слова var это строго функция, а для let - любой функциональный блок. Для примера используем var, которая используется внутри какой-либо функции:
function iterator() {
var counter = 0;
}Как мы знаем, переменная, объявленная внутри определенной области видимости, не будет доступна извне. В случае, если такая переменная уже существует в родительской области видимости, она будет переобъявлена. Что же касается всех последующих дочерних областей видимости, переменная counter в них будет доступна. К примеру, давайте внутри нашей функциии iterator мы собъявляем в качестве возвращаемого значения другую функцию:
function iterator() {
var counter = 0;
return function increment() {
return ++counter;
}
}Обратите внимание, что переменная counter не была переобъявлена, но была переиспользована. Внутри функции increment мы пользуемся поступностью переменной, объявленой в более высокой области видимости. И самое интересное: давайте воспользуемся написанным выше кодом:
var counterValue;
var increment = iterator();
counterValue = increment(); // 1
counterValue = increment(); // 2
counterValue = increment(); // 3В результате вызова функции iterator(), нам предоставилась возможность использовать функцию increment() в другой области видимости. При этом, оригинальная функция iterator() продолжила иметь доступ к переменной counter в области видимости, где она была объявлена.
Ситуация, в которой функция может использовать переменные области видимости, внутри которой она была объявлена, и называется замыканием.
Для того, чтобы сделать наш модуль переиспользуемым, давайте его модифцируем:
function iterator(initialValue) {
var counter = initialValue || 0;
return {
inc: function() { counter++; },
dec: function() { counter--; },
val: function() { return counter; },
reset: function() { counter = 0; }
}
}Благодаря данной модификации, будет возможно уменьшать и даже сбрасывать счетчик, причем каждая из трех объявленных функций будет иметь доступ к переменной counter.
var counterValue;
var iterate = iterator(4); // Устанавливаем начальное значение счетчика
iterate.inc(); // 5
iterate.dec(); // 4
iterate.reset(); // 0
iterate.inc(); // 1
console.log(iterate.val());Итог
- Замыкание в Javascript встречается повсеместно. Чтобы получить замыкание, достаточно объявить одну функцию внутри другой.
- С помощью замыкания можно организовать приватный доступ к данным.