Со времени обновления ES6 в JavaScript есть три типа областей видимости:
- Глобальный охват
- Объем функции
- Область действия блока
Что такое область действия с точки зрения контекста выполнения?
Глобальная область видимости - это глобальный контекст выполнения, а область действия функции связана с контекстом выполнения функции.
Область видимости блока, представленная в ES6, отличается от двух своих братьев и сестер.
Пример глобальной области видимости
Самый простой способ понять область действия блока - сравнить ее с двумя другими областями.
Переменная работает аналогично в глобальной области и области функций, поэтому в этом посте я буду говорить только о глобальной области и области блока.
В этом случае у нас есть только один глобальный контекст выполнения и одна среда глобальных переменных.
Второе apple
присвоение отменяет предыдущее. В конце выполнения остается только одна переменная apple
, содержащая значение «банан».
С точки зрения области видимости, мы можем сказать, что переменная apple
находится в глобальной области видимости.
Область действия блока
Мы можем переписать приведенный выше пример с let
, чтобы ввести новую область видимости, область видимости блока.
Консоль регистрирует два разных значения. Первая переменная apple
содержит значение «яблоко», а переменная в блоке if
имеет значение «банан»,
Почему у нас есть две переменные с одинаковыми именами?
Лексическая среда
Давайте рассмотрим двухэтапный процесс и проясним, как это работает.
На этапе компиляции неопределенная переменная apple
добавляется в глобальный контекст выполнения.
В этот момент движок JavaScript решает пропустить второй apple
по двум причинам:
- это переменная, созданная с помощью
let
, и - это в области блока.
Далее начинается этап выполнения. Первой переменной apple
присваивается значение «яблоко».
При чтении блочных кодов if
происходит вложенный этап компиляции. Создается вторая неопределенная переменная apple
.
Вместо того, чтобы создавать ее в переменной среде, эта apple
переменная добавляется в лексическую среду.
Вскоре apple
в лексической среде присвоено значение «банан».
Теперь у нас есть две переменные с одинаковыми именами, управляемые в двух средах. Именно так движки JavaScript работают с let
и по-прежнему обратно совместимы с var
.
Стек области видимости в лексической среде
Чтобы лучше понять разницу между let
и var
, давайте объединим их вместе в забавном примере.
На этапе компиляции неопределенные переменные apple
и grape
инициализируются в переменной окружения. Поднимается grape
инициализация. Между тем в лексической среде создается banana
переменная.
Казнь начинается. apple
присваивается значение «глобальное яблоко», а banana
- «глобальный банан».
Пора позаботиться о переменных в блоке.
Эй, это еще одна banana
переменная. Можем ли мы иметь две banana
переменных в одной лексической среде?
При просмотре переменных let
и const
в области видимости блока JavaScript создает для них отдельную область. Лексическая среда поддерживает стековую структуру своих переменных, поэтому переменные с одинаковыми именами не конфликтуют друг с другом.
Здесь неопределенные переменные banana
и orange
находятся в резервной области.
Вскоре обоим будет присвоено значение соответственно.
После выполнения последнего присваивания все переменные готовы.
При регистрации первой переменной движок JavaScript сначала пытается найти apple
в лексической среде сверху вниз. Затем он проверяет среду глобальных переменных и находит apple
, выходя из системы «глобальное яблоко».
При поиске banana
движок JavaScript выполняет те же действия, находит его и регистрирует «блочный банан».
На данный момент в блоке больше не осталось исполняемых кодов. Область действия блока удалена.
Скрипт продолжает выполнение. Он находит banana
и grape
в среде глобальной переменной и выполняет выход из системы «глобальный банан» и «глобальный виноград» соответственно.
Когда сценарий ищет orange
, переменная нигде не существует, потому что область, в которой существовалаorange
, была удалена. Выдает ошибку «оранжевый не определен».
Весь сценарий заканчивается.
Есть ли какие-нибудь еще проблемы, связанные с let
и const
, кроме прицелов?
Уловки создания, инициализации и назначения
От компиляции до выполнения переменная проходит три этапа:
- Творчество
- Инициализация
- Назначение
Что будет в лог консоли? Это apple
? Или это banana
?
Удивительно, но отображается сообщение об ошибке «Нет доступа apple
перед инициализацией».
Эта ошибка связана с подъемом.
- Для переменной
let
поднимается ее создание, но не инициализация и назначение. - Для переменной
var
поднимаются ее создание и инициализация, но не назначение. - Для
function
его создание, инициализация и назначение выполняются одновременно.
Перед инициализацией переменной область кода назвали временной мертвой зоной.
- Если вы попытаетесь получить доступ к переменной до создания, вы увидите ошибку «[имя переменной] не определено».
- Если вы решите получить доступ к переменной до инициализации, вы увидите ошибку «Невозможно получить доступ к [имя переменной] до инициализации».
- Если вы зарегистрируете переменную перед назначением, вы увидите значение
undefined
.
Расскажем все, что вам нужно знать об объеме и лексическом окружении.
Какие выводы?
- Лексическая среда - еще один компонент среды выполнения.
- Переменные
let
иconst
в области блока создаются на этапе выполнения вместо компиляции. - Эти переменные хранятся в лексической среде.
- Множественные области видимости блоков поддерживаются как структура стека в лексической среде.
- Когда механизм JavaScript выполняет все коды в области блока, соответствующие переменные
let
иconst
удаляются.
Присоединяйтесь к Medium
Приобретение среднего членства по указанной выше ссылке означает, что я могу получать доход по реферальной ссылке. Это не означает, что вы должны покупать по ссылке, и я не отрицаю и не выступаю против других каналов. Это ваше право знать.
Следующий…
дальнейшее чтение
- Если вы хотите узнать иное понимание лексической среды, этот пост стоит прочитать.
- Если вы не знакомы с подъемником, надеюсь, мой пост может помочь.
- Этот ответ исчерпывающий, объясняющий временную мертвую зону.