Safari JS引擎在with语句内调用同域函数报let变量未定义是否为Bug
结论
这段代码完全符合ECMAScript规范要求,应当正常运行不抛出错误,你遇到的是Safari内置JavaScriptCore引擎的已知Bug。
规范层面的逻辑说明
with语句的作用是在当前作用域链顶端临时插入一个指定的对象上下文,仅影响未被声明过的自由变量的查找优先级,不会改变已有声明的词法绑定规则:
- 你代码中用
let声明的变量a属于with块的块级作用域绑定,和with插入的空对象没有关联 - 函数
foo的词法作用域天然可以访问同一块级作用域下的变量a
Chrome和Firefox的执行逻辑完全符合规范要求。
Safari出错的原因
Safari的JS引擎在处理with块内的块级声明(let、const、块级函数)时存在作用域解析缺陷,错误地将块内所有变量的查找都优先绑定到with插入的对象上,忽略了块级作用域的绑定,才会抛出变量a未定义的错误。
把let a换成var a可以绕开这个问题,是因为var属于函数/全局级别的声明,Safari对var的作用域解析逻辑不受该Bug影响。
内容的提问来源于stack exchange,提问作者joe
相关产品推荐
相关产品推荐

