2017-06-20 92 views
1

在传统for循环的初始化表达式中使用let时,它的作用域为for循环的块。在for循环的初始化表达式中声明的变量始终在词法上始终在体内

细则中指出:

letconst声明定义被限定在 运行变量执行上下文的LexicalEnvironment

是否意味着的i声明的一点是(甚至在ES5是(?))词法(语义我知道使用var将它悬挂)块包括主体for循环(因为它天真地看起来好像它是外面它)。

或者这是否意味着这是let和/或for循环的新特性,使其具有词法上在循环体内的语义?

要清楚:我知道可见性语义是新的(即let的块范围与var的功能范围)。我对定义的词汇位置是否总是被置于循环体内感兴趣。

for(let i = 0; i < 10; i++) { 
    // the body of the loop.... 
} 
+0

“*这是否意味着的'我申报点'在包含for循环体的块内是词法上的?*“ - 不,你是怎么想的? – Bergi

+1

相关:[let'的语义和block for scoping for循环](https://stackoverflow.com/q/30899612/1048572) – Bergi

+0

不应该使用[tag:language-lawyer]标记该帖子吗? – Dragomok

回答

2

其实,把它想象成一个假想的包装块,其中所有的for声明的变量都是别名。有点像这样:

// Original 
for (let i = 0; i < 10; i++) { ... } 

// Equivalent 
{ 
    let _i; 
    for (_i = 0; _i < 10; _i++) { 
     let i = _i; 
     ... 
     _i = i; 
    } 
} 

它通过创建for内一个新的范围,别名变量,然后有效地在每个块的最后更新的别名。

(当然,发动机实现它不同于此,但是当你进入编译原理和观测的语义和实际执行之间的差异很。)

+0

在ES2015中,初始化表达式中的'var'声明是为了在for循环体块内部或外部拥有一个**词法**声明点? – Ben

+0

'var'被挂起到函数顶部,就像它一直有的一样。在这方面没有任何改变。 –

+0

绑定每迭代功能不适用于具有传统for循环的'const'。然而,'let','const' *的提升行为与你的答案相同。每次迭代绑定行为是我理解中缺少的一部分。 – Ben