https://habr.com/ru/company/plarium/blog/450988/- JavaScript
- Программирование
- Блог компании Plarium
Представляем вашему вниманию перевод статьи Parathan Thiyagalingam, опубликованной на сайте medium.freecodecamp.org. Хотите узнать, как работают замыкания в JavaScript? Загляните под кат!
Фото Austin Distel с Unsplash
Замыкание — это комбинация всех переменных в области видимости на момент создания функции. Чтобы использовать замыкание, нужно создать вложенную функцию, то есть функцию внутри функции. У внутренней функции будет доступ к переменным в области видимости внешней функции даже после того, как внешняя функция завершит работу. (Именно
замыкание обеспечивает этот доступ.) Каждый раз, когда создается функция, создается и замыкание.
Перед тем как начать разбираться с понятием замыканий, рассмотрим, что такое цепочки областей видимости в JavaScript.
Как правило, выделяют два типа областей видимости: глобальные и локальные.
В JavaScript переменная внутри функции не доступна снаружи — в отличии, например, от переменных внутри блока (в условиях вроде
if
и
while
).
Исходя из этого, у функции в JavaScript есть область видимости, а у блока — нет.
var a = 10;
function app(){
var b = 2;
console.log(a); // 10
console.log(b); // 2
}
console.log(b); // ReferenceError: b is not defined
app();
Как мы уже знаем,
a — глобальная переменная, а
b — локальная, то есть используемая только функцией
app
. Вне локальной области видимости у нас нет доступа к локальной переменной.
Как использовать вложенную функцию (функцию внутри функции)
var a = 10;
function app(){
var b = 2;
var d = 3;
function add(){
var c = a + b;
}
return add;
}
var x = app();
console.dir(x);
На примере выше
app
— это родительская функция,
add
— дочерняя.
- Для отображения всех свойств выбранного объекта вместо console.log используется console.dir.
- Переменная х присваивается функции
app
, которая далее возвращает функцию add
. Это позволяет увидеть все свойства объекта функции add
.
Если вы откроете консоль в браузере, то обнаружите объект
Closure
внутри массива данных
Scopes
.
Поскольку внутренняя функция
add
имеет доступ к переменным
b и
d, которые принадлежат внешней функции, эти две переменные будут добавлены в объект
Closure
в качестве ссылки.
Рассмотрим еще один пример замыкания.
var a = 10;
var startFunc;
function app(){
var b = 2;
function add(){
var c = a + b;
console.log(c);
}
startFunc = add();
}
app(); // Invoke the app function
startFunc;
// as the app function invoked above will assign the add function to startFunc & console the value of c
- Глобальной функции
startFunc
присваивается функция add
, которая является дочерней для родительской функции app
.
- Это становится возможным только после вызова функции app. В противном случае функция
startFunc
будет вести себя как глобальная переменная без присвоенного значения.
Как использовать замыкания в JavaScript
Многие из нас, используя замыкания при написании кода, не до конца понимают, почему это делают. В JavaScript отсутствуют модификаторы
public,
protected и
private, которые есть в языках объектно-ориентированного программирования. Поэтому, чтобы закрыть доступ к пространству имен для внешнего кода, мы вынуждены прибегать к помощи функций.
И раз уж речь зашла о функциях —
немедленно вызываемая функция (IIFE) запускается сразу после объявления. Ее даже не нужно вызывать.
Синтаксис IIFE выглядит так:
(function(){
//variables & scope that inside the function
})();
Рассмотрим такой пример:
var studnetEnrollment = (function () {
//private variables which no one can change
//except the function declared below.
var count = 0;
var prefix = "S";
// returning a named function expression
function innerFunc() {
count = count + 1;
return prefix + count;
};
return innerFunc;
})();
var x = studnetEnrollment(); // S1
console.log(x);
var y = studnetEnrollment(); // S2
console.log(y);
count
и
prefix
— две приватные переменные, которые невозможно изменить. Доступ к ним открыт лишь для внутренней функции (в нашем случае это функция
innerFunc
).
- При первом вызове функции
studentEnrollment
функция innerFunc
увеличивает значение переменной count
до 1.
- Во второй раз значение
count
увеличивается с 1 до 2.
- Все это возможно только благодаря замыканию.
Заключение
Замыкание — это набор переменных внешней функции, благодаря которому область видимости внутренней функции получает доступ к этим переменным. Таким образом обеспечивается защита глобального пространства имен.
Функционал замыканий позволяет разработчикам писать чистый код — такой, как в языках объектно-ориентированного программирования, код, в котором не путаются глобальные и локальные переменные.
Приятного кодинга!