HTML / CSSJavaScriptNode jsПаттерны проектированияПрактические

Замыкания

closures
:pencil:Замыкание(Closures)

Замыкание - это прием, с помощью которого можно "скрыть" переменные в контексте родительской функции, возвращающей функцию.

function execution scope

Функция в JS находится сразу в двух контекстах:

  • Динамический контекст - это контекст вызова функции - значение параметров и окружение на момент вызова;

  • Лексический контекст - контекст времени определения функции, её вложенности в другие области видимости, доступ к которым функция имеет и после окончания выполнения функций-владельцев этих областей видимости.

lexical context
:pencil:Контекст выполнения

Контекст выполнения — это абстрактное понятие, которое используется в спецификации 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}
7
8var child = parent ( "Hello! " )
9var child1 = parent ( "Hey! " )
10
11child() // Hello! I'm superman
12child1() // Hey! I'm superman
13child() // Hello! I'm superman
14child1() // Hey! I'm superman

Кажется, как будто функция «запоминает» это окружение, поскольку функция буквально имеет ссылку к области видимости и переменным, определённым в этой среде.

Функция counter

1function makeCounter(){
2 var counter = 0;
3
4 return function(){
5 return counter++;
6 }
7}

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

1function makeCounter(){
2 var counter = 0;
3
4 function increment(){
5 return counter++;
6 }
7
8 function decrement(){
9 return counter--;
10 }
11
12 function read(){
13 return counter;
14 }
15
16 return {
17 increment:increment,
18 decrement: decrement,
19 read:read
20 };
21}

Результатом выполнения makeCounter будет обькт с методам для счетчика.

Самостоятельная работа 🏡☕️

Используя функцию makeCounter расширить функционал:

  • Добавить reset при вызове котого счетчик будет сбрасываться в начальное состояние.
  • Добавить возможность при создании счетчика указывать начальное знаечение (по умолчанию 0) и шаг для increment и decrement (по умолчанию 1)

Практика 👩‍💻👨‍💻

Задание :one:

Переделайте задание 2 из прошлой практики так, что бы в нем не было глобальных перееменных.

Hello