Задать вопрос
IlyaMalone
@IlyaMalone
Frontend Developer

Лексическое окружение и замыкание. Правильно ли понимаю?

Всем привет! Я новичок и пытаюсь разобраться на тему: "Замыкания в JS".
Просьба помочь разобраться, т.к. сижу и не могу до конца понять следующее:

Вопрос 1. Правильно ли я понимаю данные термины:
Контекст выполнения - это окружение, в рамках которого выполняется код. Т.е. как я понимаю, контекст выполнения - это кусок кода который в настоящий момент выполняется.
Перед запуском JS-кода создается контекст выполнения, который в свою очередь подразделяется на несколько этапов:
1. Привязка this
2. Формирование Lexical Environment (лексического окружения)
3. Формирование Variable Environment (окружения переменных) - тут непонятно зачем? Если данные
переменных хранятся в лексическом окружении?
Лексическое окружение - это некий скрытый объект, у которого есть 2 компонента:
а) запись окружения - это просто хранилище данных, переменных, функций и их значений. Т.е. просто в памяти сохранились значения для их дальнейшего использования.
b) ссылка на внешнее окружение. Тут не пойму для чего это. Т.е. тут как бы, какие внешние данные доступны в текущем окружении, верно?)

Помимо всего прочего я знаю, что при вызове функции каждый раз создается новое лексическое окружение данной функции и тут вопрос уже связан непосредственно со счетчиком:

function makeCounter() {
  let count = 0;
  return function() {
    return count++;
  };
}

let counter1 = makeCounter();
let counter2 = makeCounter();

alert( counter1() ); // 0
alert( counter1() ); // 1

alert( counter2() ); // 0 (независимо)


Вот у нас есть счетчик, оформленный с помощью замыкания.

Вопрос 2. Почему при первом alert(counter()) мы получаем значение: 0?
При первом alert(counter()) создается новое лексическое окружение этой функции:
- объявляется переменная let count со значением: "0",
- и вызов функции counter должен при первого alert возвращать 1, т.к. выполняется return count++ почему же он возвращает: "0"?

Вопрос 3. Почему если мы вызываем повторно функцию alert, то счетчик будет увеличиваться, если для каждого вызова функции создается новое лексическое окружение, т.е. при каждом вызове должно возвращаться одно и то же значение. Т.е. разные лексические окружения создаются при вызовах и они между собой никак не связаны.

Помогите пожалуйста понять и разобраться с данными вопросами. Будут предельно благодарен!
  • Вопрос задан
  • 131 просмотр
Подписаться 1 Простой 7 комментариев
Решения вопроса 1
Stalker_RED
@Stalker_RED
1. В целом понимание правильное, но не до конца.

2. return count++ вернет 0, и после этого увеличит счетчик. Если бы было return ++counter;, то вернулось бы уже измененное значение. Читайте разницу префиксного и постфиксного инкремента.

3. makeCounter() вызывается дважды, дальше идут вызовы counter1 или counter2, LE которых было создано при вызове makeCounter.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы