Не могу найти, где ECMAScript упоминал цепочку о области видимости

#javascript

Вопрос:

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

Нравится

  1. Пусть oldEnv-это лексическая среда контекста выполняемого выполнения.
  2. Пусть blockEnv-это новая объявленная среда(oldEnv).
  3. Выполните установку объявления о блокировке(StatementList, blockEnv).
  4. Задайте для лексической среды контекста выполняемого выполнения значение blockEnv.
  5. Пусть значение blockValue является результатом оценки StatementList.
  6. Установите для лексической среды контекста выполняемого выполнения значение oldEnv.
  7. Возвращаемое значение блока.

правильно, лексическая среда теперь указывает на блокенв, который является декларативной записью среды

но это не говорит о том, в каком месте мы ищем переменные.

основываясь на логике, я предполагаю, что это поиск внутри лексической среды.

я спрашиваю, где я могу найти правило, в котором указано место, где мы ищем переменные и функции.

Ответ №1:

Цепочка областей реализуется с помощью свойства [[OuterEnv]] объектов среды.

Каждая запись среды содержит поле [[OuterEnv]], которое либо равно нулю, либо является ссылкой на запись внешней среды. Это используется для моделирования логической вложенности значений записей среды. Внешняя ссылка на (внутреннюю) запись среды-это ссылка на Запись среды, которая логически окружает запись внутренней среды.

В принципе, при поиске привязки для идентификатора используется текущий объект среды, и если соответствующая привязка не найдена, используется привязка, связанная через [[OuterEnv]], и так далее.

Вы можете видеть это в ResolveBinding, который использует GetIdentifierReference. Если GetIdentiferReference on не находит привязки к объекту среды, с которым он вызывается, он рекурсивно вызывает себя с помощью [[OuterEnv]]этой среды:

  • Если env имеет значение null, то
    • Верните ссылочную запись { [[База]]: неразрешимая, [[Имя ссылки]]: имя, [[Строгое]]: строгое, [[Значение]]: пустое }.
  • Пусть будет так ? зав.Имеет привязку(имя).
  • Если сущее истинно, то
    • Верните ссылочную запись { [[База]]: env, [[Имя ссылки]]: имя, [[Строгое]]: строгое, [[Значение]]: пустое }.
  • Ещё,
    • Пусть внешнее будет завистью.[[Внешний вид]].
    • Вернуться ? GetIdentifierReference(внешний, имя, строгий).

В комментарии вы спросили, зачем нам нужна переменная среда. У нас есть как переменная среда, так и лексическая среда (и глобальная среда, если на то пошло), которые являются объектами записи среды (1, 2). Нам нужна переменная среда по сравнению с лексической средой, чтобы обрабатывать var объявления с областью действия иначе , чем объявления с лексической областью let действия ( const , и т.д.). Например:

 function example() {
    // Here, the LexicalEnvironment and the VariableEnvironment
    // are the same environment record; let's call it "outer"
    var a = 1; // Created in "outer"
    {
        // Here, there's a new environment set as the LexicalEnvironment,
        // using "outer" as its [[OuterEnv]. Let's call it "inner". See
        // https://tc39.es/ecma262/#sec-block-runtime-semantics-evaluation
        var b = 2; // Created in "outer"
        let c = 3; // Created in "inner"
        console.log(typeof a); // "number", found in "outer"
        console.log(typeof b); // "number", found in "outer"
        console.log(typeof c); // "number", found in "inner"
    }
    console.log(typeof a); // "number", found in "outer"
    console.log(typeof b); // "number", found in "outer"
    console.log(typeof c); // "undefined", not found at all
}
example(); 

Комментарии:

1. так зачем же нам переменная среда, если все работы выполняются с лексической средой. когда мы заглянем внутрь переменной среды ?

2. @AngryJohn — Переменные среды-это записи среды, они просто не единственные. (У меня не должно было быть «лексического» в моем первом абзаце.) Нам нужна переменная среда, отличная от лексической среды , для обработки var деклараций с областью действия, отличной от деклараций с лексической областью ( let , const и т. Д.) (И для старого with оператора).

3. @AngryJohn — Я добавил пример, который, я думаю, поможет.

4. Да, но если в начале файл и пять являются одной и той же записью среды, зачем нам нужна копия ? да, когда мы вызовем пример функции, будет создан новый файл, который будет указывать на функцию ER. и все переменные в этой функции будут перенесены в эту функцию ER, и когда мы достигнем блока в вашем примере, будет создан новый файл, и теперь файл будет указывать на этот файл. новый DER[[OuterEnv]] будет указан на старый Env, который в данном случае является функцией ER. после того, как мы дойдем до конца блока, файл будет указан обратно на функцию ER, так в чем же смысл этого VE.

5. кстати, извините, если мой английский звучит так, как будто говорит 6-летний ребенок. английский не мой родной язык (: