JavaScript 拥有块级作用域的语句
什么是单语句
就是无法创建块级作用域的语句
- 为什么单语句中不能出现词法声明?
以下代码运行都会报错:SyntaxError: Lexical declaration cannot appear in a single-statement context
if(true) let x=2
while (true) let x = 200;
因为单语句没有块级作用域,而词法声明是不可覆盖的,单语句后面的词法声明会存在潜在的冲突。
// 以下代码中只有一个块级作用域,也就是说在一个块级作用域中,x 被重复用 let 声明了 let x=3 if(false) let x=2
拥有块级作用域的语句
// 例 1 try { // 作用域 1 } catch (e) { // 表达式 e 位于作用域 2 // 作用域 2 } finally { // 作用域 3 } // 例 2 //(注:没有使用大括号) with (x) /* 作用域 1 */; // <- 这里存在一个块级作用域 // 例 3, 块语句 { // 作用域 1 }
除了这三个语句和“一个特例”之外,所有其它的语句都是没有块级作用域的。例如 if 条件语句的几种常见书写形式:
if (x) { ... } // or if (x) { ... } else { ... }
这些语法中的“块级作用域”都是一对大括号表示的“块语句”自带的,与上面的“例 3”是一样的,而与 if 语句本身无关。
语句为什么要构建自己的作用域
- 标识符管理
- 在语法上支持多语句(例如 try…catch…finally 语句)
- 语句所表达的语义要求有一个块,例如“块语句{ }”在语义上就要求它自己是一个块级作用域。
for(let i=0;i<5;i++) console.log(i)
- for(let...) 本身有一个块作用域,称为
forEnv
- for(let...) 循环体,这里的循环体有一个作用域,称为
loopEnv
- 在实际运行时,每一次迭代都会创建一个
loopEnv
的副本,记为iterationEnv
for (let i=0;i<4;i++) setTimeout(()=>console.log(i), 1000);
注意上面三类作用域的关系是:
forEnv
是loopEnv
的父级作用域,iterationEnv
有迭代数量个,每个都是loopEnv
的副本
上面代码等价于
for (let i=0;i<4;i++){ let j=i; setTimeout(()=>console.log(j), 1000); }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

上一篇: JavaScript 变量声明/赋值
下一篇: 彻底找到 Tomcat 启动速度慢的元凶
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论