为何JavaScript引擎优先报错let重复声明,而非const提前访问错误?
为什么先抛出重复声明的SyntaxError而非提前访问的ReferenceError?
这完全是JavaScript引擎的工作机制导致的,引擎处理代码分两个关键阶段:编译阶段和执行阶段,且编译阶段会在执行阶段之前完成全部处理。
1. 编译阶段:优先拦截语法错误
在编译阶段,引擎会先通读整个代码文件,完成两项核心工作:
- 词法分析:识别代码中的标识符、关键字、运算符等元素
- 语法检查:校验代码是否符合JavaScript语法规则
其中let和const有明确的语法约束:同一作用域内不允许重复声明同一个标识符。你的代码无论是否添加顶部的console.log语句,都存在let thisIsALet = 51之后再次let thisIsALet = 50的重复声明操作,这属于语法错误,会在编译阶段被引擎直接检测到。
只要编译阶段发现语法错误,引擎会立刻抛出SyntaxError并终止后续流程——代码根本不会进入执行阶段,因此你预期的、只有执行阶段才会触发的ReferenceError完全没有机会暴露出来。
2. 验证:去掉重复声明后的结果
如果删掉重复声明的代码,修改为如下内容:
console.log(thisIsAConst) const thisIsAConst = 50 const constObj = {} constObj.a = 'a' let thisIsALet = 51 thisIsALet = 50
此时编译阶段没有语法错误,引擎会进入执行阶段,这时才会触发ReferenceError: Cannot access 'thisIsAConst' before initialization——因为const变量存在暂时性死区,在声明语句执行前无法被访问。
总结
一句话概括:语法错误(比如重复声明)是编译阶段就会被拦截的“致命错误”,会直接阻断代码执行;而变量提前访问的错误是执行阶段才会触发的逻辑错误,只有当编译阶段完全通过后才有机会出现。
内容的提问来源于stack exchange,提问作者Dat Pham
相关产品推荐
相关产品推荐

