JavaScript 拥有块级作用域的语句

发布于 2024-05-22 22:55:37 字数 1628 浏览 64 评论 0

什么是单语句

就是无法创建块级作用域的语句

  • 为什么单语句中不能出现词法声明?

以下代码运行都会报错: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 语句本身无关。

语句为什么要构建自己的作用域

  1. 标识符管理
  2. 在语法上支持多语句(例如 try…catch…finally 语句)
  3. 语句所表达的语义要求有一个块,例如“块语句{ }”在语义上就要求它自己是一个块级作用域。

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);

注意上面三类作用域的关系是: forEnvloopEnv 的父级作用域, iterationEnv 有迭代数量个,每个都是 loopEnv 的副本

上面代码等价于

for (let i=0;i<4;i++){
    let j=i;
    setTimeout(()=>console.log(j), 1000);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

嗳卜坏

暂无简介

文章
评论
27 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文