Замыкание и лексическое окружение в JavaScript
Сегодня разберем, использование замыканий в JavaScript.
Возьмем небольщой кусок кода, который уже попадался в этом курсе
let number = 5;
function logNumber() {
console.log(number);
}
number = 6;
logNumber();
Нужно помнить что JavaScript выполнит этот код с помощью интерпритатора последовательно, строка за строкой.
На строчке let number = 5
тип данных изначально
будет undefined
мы туда помещаем значение 5
Дальше интерпритатор натыкается на создание функции.
Переменная logNumber
прописана с помощью functon declaration
и поэтому она уже существует в контексте еще до того как
интерпретатор дойдет до нее, когда пойдет по коду построчно.
И мы можем вызвать эту функцию до ее объявления.
Как мы и поступили.
Обратим внимание что logNumber
идет без аргументов, это
значит что функции потребуется откуда то взять number
Это мы сейчас и будем выяснять.
Дальше в нашем коде идет перезапись значения переменной
number
- мы меняем значение 5
на 6
И в самом низу, идет запуск самой функции.
Когда она воспроизводится, функция обращается к какому-то
значению number
и возвращает нам значение. Давайте
узнаем об этом подробнее.
Как и ожидалось, при запуске кода, в консоль получаем
цифру 6
- это актуальное значение переменной number
Поскольку внутри функции, сначала идет обращение к
переменной number
по ссылке, то наша функция
сначала проверяет первое значение, которое равно 5,
а потом чекает дальнейшие изминения, и выкидывает
в консольку актуальное значение.
Давайте попробуем разобраться, почему так происходит не только на уровне логики, но и вообще на уровне внутренностей языка JavaScript
Тут следует разобрать такое понятие как “Лексическое Окружение”
Лексическое Окружение
В JavaScript у каждой выполняемой функции, блока кода есть скрытый объект, который называется - “лексическое окружение”
Это внутренний, технический и скрытый объект.
Лексическое окружение делится на 2 части, на внутренее и на внешнее.
Для того чтобы увидеть, что происходит с кодом в нашем примере, воспользуемся дебаггером и брейкпоинтом
let number = 5; debagger
function logNumber() {
console.log(number);
}
number = 6;
logNumber(); debagger
Внесем небольшие изминения в наш пример и добавим строчку во внутреннюю область видимости функции, с новым значением переменной.
let number = 5; debagger
function logNumber() {
let number = 4; debagger
console.log(number);
}
number = 6;
logNumber(); debagger
В консоль выведется значение локальной переменной
которая равна 4
Замыкание в функции, если говорить простыми словами, то это когда функция что то ищет локально, и если не находит то происходит обращение к глобальному коду.