如何在词汇环境中管理块范围?

时间:2015-04-02 10:06:20

标签: javascript ecmascript-6

如果我使用var在函数中声明变量,那么该变量的插槽将添加到该函数定义的LexicalEnvironment

function() {
  var foo; 
}

在上面的代码中,与该功能相关联的LexicalEnvironment包含一个包含密钥foo且值为undefined的广告位。

如果我使用块范围声明,周围的LexicalEnvironment如何受到影响?

function() {
  {
    let foo; // How does this affect the LexicalEnvironment?
  }
}

2 个答案:

答案 0 :(得分:4)

function() {
  var foo; 
}

正如您所提到的,foo中的LexicalEnvironment对于该函数中的所有内部函数都是全局的。

但是

function() {
  {
    let foo; // How does this affect the LexicalEnviroinment?
  }
}

此处foo仅对该块是本地的。它不会在那个街区外面看到。

它如何影响LexicalEnvironment

如果您在该区块内的任何位置引用foo,则本地let foo将覆盖您在该功能中定义的全局var foo

  

关于ES6,

function example(x) {
    console.log(y); // ReferenceError: y is not defined
    if (x) {
        let y = 5;
    }
}

使用let语句声明的变量被创建为当前执行上下文的词法环境而不是变量环境的绑定。 ES6中块语句规范的更改意味着每个块都有自己的词法环境。在上面的示例中,在计算块(if语句的主体)时会创建一个新的词法环境。当评估let语句时,绑定被添加到这个词法环境中,并且不能从外部词法环境(函数声明本身)环境中获取。

<强> Refer

答案 1 :(得分:1)

最好通过查看spec

来回答这样的问题
  

阻止:{ StatementList }

     
      
  1. oldEnv 成为running execution context’s LexicalEnvironment
  2.   
  3. blockEnv 成为NewDeclarativeEnvironment oldEnv )。
  4.   
  5. 执行BlockDeclarationInstantiation StatementList blockEnv )。
  6.   
  7. running execution context’s LexicalEnvironment设置为 blockEnv
  8.   
  9. blockValue 成为评估 StatementList 的结果。
  10.   
  11. running execution context’s LexicalEnvironment设置为 oldEnv
  12.   
  13. 返回 blockValue
  14.         

    注意:无论控制如何离开Block,LexicalEnvironment总是恢复到以前的状态。

那么这里会发生什么?

评估块时,会创建一个新的词法环境,当前词汇环境为&#34; parent&#34;。在评估块的过程中,新环境将替换当前环境。

  

如果我使用块范围声明,周围的LexicalEnvironment如何受到影响?

除了暂时更换外,它根本不受影响。