Какая разница между "LexicalEnvironment" и "VariableEnvironment" в спецификации

Я читаю спецификацию ECMAScript 2015, и термины "LexicalEnvironment" и "VariableEnvironment" используются много раз. Они определены в таблице 23:

LexicalEnvironment: определяет лексическую среду, используемую для разрешения ссылок на идентификаторы, созданных кодом в этом контексте выполнения.

VariableEnvironment: определяет лексическую среду, среда EnvironmentRecord которой содержит привязки, созданные переменными элементами в этом контексте выполнения.

Компоненты LexicalEnvironment и VariableEnvironment контекста выполнения всегда являются лексическими средами. Когда создается контекст выполнения, его компоненты LexicalEnvironment и VariableEnvironment изначально имеют одинаковое значение.

Итак, я хочу знать, как они будут отличаться, и в каких ситуациях каждый из них используется. Может ли кто-нибудь объяснить?

Ответ 1

Я отправляю вопрос в официальную организацию ECMA262 по github, это ответ littledan:

Лексическая среда является локальной лексической областью, например, для let-defined переменных. Если вы определяете переменную с let в блоке catch, она видна только внутри блока catch и для реализации этого в спецификации мы используем LexicalEnvironment. VariableEnvironment - это область для таких вещей, как переменные var. вары можно рассматривать как "подъем" в верхней части функции. Чтобы реализовать это в спецификации, мы предоставляем функции новой переменной VariableEnvironment, но говорим, что блоки наследуют окружение VariableEnvironment.

Ответ 2

Это сложно. Я попытаюсь объяснить с помощью некоторых простых примеров. Итак, одна важная вещь в этом вопросе также заключается в понимании execution context.

Лексическая среда

Значит, где вы пишете что-то в коде. Не все языки программирования такие, но javascript есть.

Итак, если у вас есть функция типа

function hello() {
    var myVar = 'hello';
}

Теперь переменная myVar сидит лексически внутри функции. Это физически код, который вы пишете. Короче говоря, если говорить о lexical environment означает, где он написан и что его окружает.

Переменная среда Каждый раз, когда вы вызываете функцию, будет создан новый контекст выполнения. Поэтому даже myVar объявляется 3 раза (см. Следующий пример), они не касаются друг друга. Это когда вы говорите о Variable Environment

function b() {
    var myVar;
    console.log('three', myVar) // three undefined 
                                // cause myVar is newly declared in b()
                                // but has no value
}

function a() {
    var myVar = 2;
    console.log('two', myVar) // two 2
    b();
}

var myVar = 1;
console.log('one', myVar) // one 1
a();
console.log('four', myVar) // one 1