JavaScript中let变量使用需加分号?有无分号的行为差异解析
该问题由JavaScript自动分号插入(ASI)规则与
let的暂存死区特性共同导致 无分号代码的解析错误原因
你给出的无分号代码:
let a = 1 let b = 2 [a,b]=[b,a]
不会触发自动分号插入,因为JavaScript的ASI规则不会在以方括号[开头的行前自动补分号,引擎会将第二行和第三行合并解析为一条语句:
let b = 2[a,b] = [b,a]
解析这条语句时,引擎需要先计算2[a,b]的值(此处a,b是逗号表达式,最终取b作为索引尝试访问数字2的属性),而此时let b正处于暂存死区,尚未完成初始化赋值,因此抛出ReferenceError: Cannot access 'b' before initialization。
加分号后正常运行的原因
前两行末尾添加分号后,引擎会明确识别三条独立语句:
let a = 1; let b = 2; [a,b]=[b,a]
执行第三行解构赋值时,a和b都已经完成初始化,因此可以正常完成变量交换。
var声明不报错的原因
var存在变量提升,会在作用域初始化阶段就完成变量创建并默认赋值为undefined,没有暂存死区限制。合并解析时读取b的值不会抛出引用错误,但此时代码逻辑会被扭曲,无法完成预期的变量交换操作,属于静默的逻辑错误。
无分号写法的规避方案
如果习惯编写无分号的JavaScript代码,需要在所有以[、(、反引号`开头的行首手动添加分号,避免ASI规则的异常合并:
let a = 1 let b = 2 ;[a,b] = [b,a]
内容的提问来源于stack exchange,提问作者Edu Marcelino
相关产品推荐
相关产品推荐

