关于块级作用域的疑问?

1.    const data = 1;
2.    if (true) {
3.        console.log(data);
4.        const data = 2;
5.        console.log(data);
6.    }

如果注释第3行,代码正常运行,结果为:2;

如果注释第4行和第5行,代码正常运行,结果为:1;

如果不做注释,第3行会报错,无法在"data"被初始化之前访问;

想问一下为什么会报错?

阅读 1.4k
2 个回答

var 命令会发生“变量提升”现象,即变量可以在声明之前使用,值为 undefined。这种现象多多少少是有些奇怪的,按照一般的逻辑,变量应该在声明语句之后才可以使用。
为了纠正这种现象,letconst 命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。称为 “暂时性死区”。

ES6 明确规定,如果区块中存在 letconst 命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。

总之,在代码块内,使用 letconst 命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。

具体关于 “暂时性死区” 的内容可以在 阮一峰老师的 《ECMAScript 6入门》 中查看。


关于你在评论中提到的执行到第三行是,会先检测当前作用域的变量定义的理解是正确的。

因为实际代码在运行的时候,会把所有的变量声明函数声明提升到最前面。函数表达式只会提升变量的声明。

关键词为:变量提升 和 函数提升。

报错原因是“暂时性死区”

ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。

总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。

具体看一下这里说很详细了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题