Замыкания
Замыкание(Closures)
Замыкание - это прием, с помощью которого можно "скрыть" переменные в контексте родительской функции, возвращающей функцию.
Функция в JS находится сразу в двух контекстах:
Динамический контекст - это контекст вызова функции - значение параметров и окружение на момент вызова;
Лексический контекст - контекст времени определения функции, её вложенности в другие области видимости, доступ к которым функция имеет и после окончания выполнения функций-владельцев этих областей видимости.
Контекст выполнения
Контекст выполнения — это абстрактное понятие, которое используется в спецификации ECMAScript для оценки времени выполнения кода.
В любой момент времени выполняется только один контекст функции (тело функции).
Вот почему JavaScript является однопотоковым, так как единовременно может выполняться только одна команда. Обычно браузеры поддерживают этот контекст с помощью стека — stack.
Стек — структура данных, выполняемая в обратном порядке: LIFO— «последним пришёл — первым вышел».
Последнее, что вы добавили в стек, будет удалено первым из него. то происходит из-за того, что мы можем только добавить или удалить элементы из верхушки стека. Текущий или «выполняющийся» контекст исполнения — всегда верхний элемент стека. Он выскакивает из стека, когда код в текущем контексте полностью разобран, позволяя следующему верхнему элементу стека взять на себя контекст выполнения.
Замыкания в javascript используются для того, чтобы скрывать значения переменных, и хранить значения функций. Суть в том, что при замыкании создается одна функция, в которой задаются переменные и которая в результате свое работы возвращает свою вложенную функцию. Затем в ней (в основной функции) создается вложенная функция, в которой делаются какие-то операции с переменными основной функции и которая возвращает результат этих операций. Далее основная функция приравнивается к какой-то переменной – эта переменная может вызываться сколько угодно раз и при этом в ней будут храниться и обновляться значения переменных основной функции т.к. она “замкнута”.
1function parent ( arg ) {2 var superman = "I'm superman"3 return function (str) {4 console.log ( arg, superman )5 }6}78var child = parent ( "Hello! " )9var child1 = parent ( "Hey! " )1011child() // Hello! I'm superman12child1() // Hey! I'm superman13child() // Hello! I'm superman14child1() // Hey! I'm superman
Кажется, как будто функция «запоминает» это окружение, поскольку функция буквально имеет ссылку к области видимости и переменным, определённым в этой среде.
Функция counter
1function makeCounter(){2 var counter = 0;34 return function(){5 return counter++;6 }7}
Функция выше создает счетчик, значение которого можно узнать из возвращаемой анонимной функции. При этом счетчик увеличится на 1. Если расширить функционал данного примера для чтения и декремента счетчика, получим, например:
1function makeCounter(){2 var counter = 0;34 function increment(){5 return counter++;6 }78 function decrement(){9 return counter--;10 }1112 function read(){13 return counter;14 }1516 return {17 increment:increment,18 decrement: decrement,19 read:read20 };21}
Результатом выполнения makeCounter будет обькт с методам для счетчика.
Самостоятельная работа 🏡☕️
Используя функцию makeCounter расширить функционал:
- Добавить reset при вызове котого счетчик будет сбрасываться в начальное состояние.
- Добавить возможность при создании счетчика указывать начальное знаечение (по умолчанию 0) и шаг для increment и decrement (по умолчанию 1)
Практика 👩💻👨💻
Задание :one:
Переделайте задание 2 из прошлой практики так, что бы в нем не было глобальных перееменных.