javascript - ES6中for循环的作用范围是什么?
问题描述
let
JavaScript for 循环中的操作范围到底是什么?
for (let i = 0; i < 3; i++) {
let i = 4;
console.log(i);
}
console.log(i);
外部console.log
抛出错误:
“未捕获的引用错误:我未定义”
它证明i
是在块操作范围内,但是,为什么i
for循环中的定义不抛出任何重复定义错误?
解决方案
循环体for
(带有let
变量声明)有两个作用域(或 LexicalEnvironments):一个作用域是迭代环境,它包含let
在for
循环声明中声明的变量,内部作用域包含在 for 循环体中声明的变量(之后{
)。这在规范中进行了描述,从13.7.4.7 Runtime Semantics: LabelledEvaluation开始
IterationStatement : for (LexicalDeclaration Expression; Expression) 语句
(这就是for
用 is 声明变量的循环let
。)
评估上述内容最终会让您:
- 让 bodyResult 为 ForBodyEvaluation(第一个 Expression,第二个 Expression,Statement,perIterationLets,labelSet)。
请注意,“语句”可以是一个块(可以以 开头{
和结尾}
,就像大多数for
循环体一样)——这非常重要,因为一个块创建了另一个词法环境。
13.7.4.8 运行时语义:ForBodyEvaluation说:
履行 ?CreatePerIterationEnvironment(perIterationBindings)。
重复,
湾。让 result 是评估 stmt 的结果。
...
e. 履行 ?CreatePerIterationEnvironment(perIterationBindings)。
whereCreatePerIterationEnvironment
创建一个包含let
在for
循环声明中声明的变量的环境:
G。对于 perIterationBindings 的每个元素 bn,执行
一世。履行 !thisIterationEnvRec.CreateMutableBinding(bn, false)。
ii. 让 lastValue 成为 ? lastIterationEnvRec.GetBindingValue(bn, true)。
iii. 执行 thisIterationEnvRec.InitializeBinding(bn, lastValue)。
因此,有两种作用域:一种由 . 创建的CreatePerIterationEnvironment
,另一种由 is 的块创建stmt
。
for (let i = 0; i < 3; i++) {
let foo = 'f';
}
这里,i
包含在外部迭代环境中,foo
包含在内部块中,这是一个不同的环境。如果您使这两个变量名称相同,则不会引发错误,因为let <variableName>
在块内部会创建一个范围为该块的变量,并且不会尝试在迭代环境中覆盖具有相同名称的变量。
推荐阅读
- mysql - SQL 第一行结果相反
- r - 计算R中每个分位数的值数?
- sql - 从 JDE 朱利安日期中减去
- llvm - llvm Linking CXX shared library ../../lib/libLTO.so undefiened referencenece to target
- javascript - 将 Javascript 数组转换为 JSON 用户定义的键/值对
- selenium - 如何断言文本框被启用或禁用
- c# - 引用的 .dll 中的对象名称更改了炸毁应用程序
- database - 每 100 天读取一次数据,直到我们在 hive 中获得完整的数据
- javascript - 使用 String.prototype.replace 删除非字母数字文本
- excel - 在 VBA 中实现超时功能以防代码卡住