【问题标题】:Clarity on the difference between "LexicalEnvironment" and "VariableEnvironment" in ECMAScript/JavaScript明确 ECMAScript/JavaScript 中“LexicalEnvironment”和“VariableEnvironment”之间的区别
【发布时间】:2013-02-08 12:18:30
【问题描述】:

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

谢谢,

【问题讨论】:

    标签: javascript ecmascript-5 ecma262


    【解决方案1】:

    据我了解,这些只是用于指代同一类型实体(词法环境)的不同名称。它们因用途不同而有不同的名称。

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

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

    LexicalEnvironment 和 VariableEnvironment 组件 执行上下文总是词法环境。当执行 上下文被创建它的 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)
    
      })();
    
    })();
    

    【讨论】:

    • 你和Bergi似乎对“LexicalEnvironment组件的值可能会改变”有不同的理解。如果您错了,请纠正我,但您似乎是在谈论词法环境组件值的变化(例如,使用变量赋值),而 Bergi 的回答是关于替换整个 LexicalEnvironment 对象的情况。现在我很困惑!
    • 我不认为我们有不同的解释。但是看看我的例子,我可以看到它可能是多么令人困惑。抱歉 :) 变量赋值当然不会改变 LexicalEnvironment 的任何内容。我只是想表明 VE 从一个函数上下文更改为另一个函数上下文,而 LE——大多数时候——只是对当前 VE 的引用。 @Bergi 提到的 catchwith 是正确的。这是 LE 和 VE 引用不同环境的两种情况(withcatch 中不需要新的 VE;只有新的 LE——能够解析其他标识符)
    • 感谢您的澄清。你说得对,赋值行和它后面的两个 cmets 是我困惑的根源。如果我可以建议,也许您应该从示例中删除它们。
    【解决方案2】:

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

    词法环境

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

    变量环境

    标识Lexical Environment,其环境记录包含此执行上下文中的VariableStatements 和FunctionDeclarations 创建的绑定。

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

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

    这种情况并不经常发生,通常两者都指同一个Lexical Environment。问题Why do catch clauses have their own lexical environment? 中给出了改变LexicalEnvironment 的一个很好的例子——参见§12.14。我可以在规范中找到发生这种情况的另一个地方是 With Statements (§12.10),其中 Object Environment Record 动态用于标识符解析 - 但变量/函数声明是静态的。

    【讨论】:

      猜你喜欢
      • 2015-08-28
      • 2010-10-29
      • 2011-09-20
      • 2016-10-02
      • 1970-01-01
      • 1970-01-01
      • 2010-10-06
      相关资源
      最近更新 更多