清晰地了解ECMAScript / JavaScript中“LexicalEnvironment”和“VariableEnvironment”之间的区别

时间:2013-02-22 19:19:38

标签: javascript ecmascript-5 ecma262

有人可以澄清这两者之间的区别,因为它们存在于执行上下文中吗?我很难阅读ECMA 262 v 5规范并清楚地看到差异。

谢谢,

2 个答案:

答案 0 :(得分:8)

两者都是执行上下文的组件(属于同一类型),但它们用于不同的目的(from the spec):

<强> LexicalEnvironment

  

标识用于解析此执行上下文中的代码所做的标识符引用的Lexical Environment

<强> VariableEnvironment

  

标识其{1}}的环境记录包含由此执行上下文中的VariableStatements和FunctionDeclarations创建的绑定。

下一段解释了为什么它们需要不同:

  

创建执行上下文时,其LexicalEnvironment和VariableEnvironment组件最初具有相同的值。在执行上下文中执行代码期间,当LexicalEnvironment组件的值可能会发生变化时,VariableEnvironment组件的值永远不会更改

这种情况不会经常发生,通常都会引用相同的Lexical Environment。问题Why do catch clauses have their own lexical environment?中提供了更改LexicalEnvironment的一个很好的示例 - 请参阅§12.14。我在规范中找到的另一个地方是Lexical Environment§12.10),其中Object Environment Record被动态地用于标识符解析 - 但变量/函数声明是静态的。

答案 1 :(得分:4)

据我了解,这些只是用于指代相同类型实体(词汇环境)的不同名称。由于目的不同,它们的名称不同。

LexicalEnvironment用于解析标识符,而VariableEnvironment用于声明变量和函数。

它们都引用了为每个执行上下文创建的词法环境(=环境记录+可选的外部词汇环境;又称范围链)。

  

一个的LexicalEnvironment和VariableEnvironment组件   执行上下文始终是Lexical Environments。执行时   上下文创建了它的LexicalEnvironment和VariableEnvironment   组件最初具有相同的值。的价值   VariableEnvironment组件永远不会更改   在执行代码期间,LexicalEnvironment组件可能会更改   在执行上下文中

伪代码中的示例:

// VariableEnvironment (global) = { __outer__: null }
// LexicalEnvironment = VariableEnvironment (global)

(function foo() {

  // VariableEnvironment (A) = { x: undefined, __outer__: global }
  // LexicalEnvironment = VariableEnvironment (A)

  var x;

  (function bar(){

    // VariableEnvironment (B) = { y: undefined, __outer__: A }
    // LexicalEnvironment = VariableEnvironment (B)

    var y;

    x = 2;

    // VariableEnvironment (A) = { x: 2, __outer__: global }
    // LexicalEnvironment is still the same as VariableEnvironment (B)

  })();

})();