ES6中for循环的作用范围是什么? [英] What's the action scope of for-loop in ES6?

查看:96
本文介绍了ES6中for循环的作用范围是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

JavaScript的for循环中let的确切作用范围是什么?

What's exactly the action scope of let in a for-loop in JavaScript?

for (let i = 0; i < 3; i++) {
  let i = 4;
  console.log(i);
}
console.log(i);

外部console.log引发错误:

未捕获的引用错误:我未定义"

"Uncaught Reference Error: i is not defined"

证明i在块操作范围内,但是,为什么在for循环中定义的i不会引发任何重复的定义错误?

It proves i is in a block action scope, however, why doesn't the i defined in the for-loop throw any duplicate definition error?

推荐答案

for循环的主体(带有let变量声明)具有两个范围(或LexicalEnvironments):一个作用域是迭代环境,它包含在for循环声明中用let声明的变量,内部作用域包含在for循环体内(在{之后)声明的变量.在规范中对此进行了描述,从 13.7.4.7运行时语义:LabelledEvaluation

The body of a for loop (with a let variable declaration) has two scopes (or LexicalEnvironments): one scope is the iteration environment, which contains the variables declared with let in the for loop declaration, and the inner scope contains variables declared inside the for loop body (after the {). This is described in the specification, starting at 13.7.4.7 Runtime Semantics: LabelledEvaluation

IterationStatement:用于(LexicalDeclaration表达式; Expression)语句

IterationStatement : for ( LexicalDeclaration Expression; Expression ) Statement

(这是用for声明变量的for循环的意思.)

(this is what a for loop which declares a variable with let is.)

评估以上内容最终会使您:

Evaluating the above eventually gets you to:

  1. 让bodyResult为ForBodyEvaluation(第一个表达式,第二个表达式,语句,perIterationLets,labelSet).

请注意,声明"可以是一个(可以像大多数for循环主体那样,以{开头并以}结尾)-这非常重要,因为块会创建另一个词汇环境.

Note that "Statement" can be a block (can start with { and end with }, as most for loop bodies do) - this is very important, because a block creates another lexical environment.

13.7.4.8运行时语义:ForBodyEvaluation 说:

  1. 执行? CreatePerIterationEnvironment(perIterationBindings).

  1. Perform ? CreatePerIterationEnvironment(perIterationBindings).

重复

b.令result为评估stmt的结果.

b. Let result be the result of evaluating stmt.

...

e.履行 ? CreatePerIterationEnvironment(perIterationBindings).

e. Perform ? CreatePerIterationEnvironment(perIterationBindings).

其中CreatePerIterationEnvironment 创建包含变量的环境for循环声明中用let声明:

where CreatePerIterationEnvironment creates an environment containing the variables declared with let in the for loop declaration:

    g.对于perIterationBindings的每个元素bn,执行

    g. For each element bn of perIterationBindings, do

       i.履行 ! thisIterationEnvRec.CreateMutableBinding(bn,false).

        i. Perform ! thisIterationEnvRec.CreateMutableBinding(bn, false).

        ii.让lastValue为? lastIterationEnvRec.GetBindingValue(bn,true).

        ii. Let lastValue be ? lastIterationEnvRec.GetBindingValue(bn, true).

       < iii.执行thisIterationEnvRec.InitializeBinding(bn,lastValue).

        iii. Perform thisIterationEnvRec.InitializeBinding(bn, lastValue).

因此,有两个作用域:一个作用域由CreatePerIterationEnvironment创建,另一个作用域由stmt所在的块创建.

So, there are two scopes: one created by CreatePerIterationEnvironment, and one created by the block that the stmt is.

for (let i = 0; i < 3; i++) {
  let foo = 'f';
}

在这里,i包含在外部迭代环境中,而foo包含在内部块中,这是一个不同的环境.如果使这两个变量名称相同,则不会引发错误,因为该块内的let <variableName>会创建一个作用于该块的变量 ,并且不会尝试覆盖变量名相同的变量. 迭代环境.

Here, i is contained in the outer iteration environment, and foo is contained in the inner block, which is a different environment. If you made those two variable names names the same, no error is thrown because let <variableName> inside the block creates a variable scoped to that block, and does not try to overwrite the variable with the same name in the iteration environment.

这篇关于ES6中for循环的作用范围是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆