Async/Await报错:ReferenceError 初始化前无法访问变量bar(JavaScript)
报错根因分析
这个报错和await的执行逻辑无关,核心是变量名冲突+let的暂时性死区(TDZ)规则共同导致的:
- JS进入
foo函数作用域时,就会提前扫描所有声明语句,发现你用let bar声明了变量,此时foo作用域内的bar标识符就被绑定到这个新声明的变量上,不会再向上查找外层的async function bar()函数。 let声明的变量存在暂时性死区规则:在当前作用域内,从进入作用域到let bar声明语句执行完成之前,访问bar变量都会直接抛出初始化前不可访问的错误。- 赋值语句
let bar = await bar()的执行顺序是先计算等号右侧的await bar()表达式,此时let bar的声明还没有完成,bar处于暂时性死区,调用bar()本质是访问未初始化的变量,直接触发报错,根本不会走到await等待Promise决议的逻辑。
认知疏漏说明
你之前误以为报错和await的执行时机有关,实际上忽略了两个核心的JS基础规则:
- 作用域内的变量绑定是进入作用域时就完成的,不是执行到声明语句才绑定,内层同名变量会直接屏蔽外层的同名标识符
- 赋值语句永远是先执行右侧表达式,再把结果赋值给左侧变量,还没等
await逻辑运行,右侧访问bar的操作就已经触发了规则报错
修复方案
只要把内层变量名改成和外层函数不冲突的名称即可,示例如下:
async function foo() { // 变量名和外层bar函数不冲突,就会正常向上查找外层的bar函数调用 let barRes = await bar(); console.log(barRes); }
内容的提问来源于stack exchange,提问作者bugsyb
相关产品推荐
相关产品推荐

