为什么可以重定义globalThis、global却不能重定义window?
差异底层原因分析
1. 核心前置规则:ES全局作用域的两类存储结构
ES规范中全局执行上下文的环境记录分为两个互相独立的存储区域:
- 对象环境记录:对应宿主提供的全局对象(浏览器为
window、Node为global),所有var声明、顶层函数声明、宿主挂载的可配置全局属性(比如globalThis、document)都存在这里,属性默认可以被遮蔽、修改。 - 声明式环境记录:专门存储
let/const/class的顶层声明,这部分内容不会挂载到全局对象上。部分宿主核心标识会被注入到这里作为不可重新声明的不可变绑定,规范明确要求:同一作用域下禁止用let/const/class重复声明已存在的绑定,违反就会抛出SyntaxError。
2. let window = undefined报错的原因
浏览器环境会将window作为核心宿主标识,直接注入到全局声明式环境记录中作为不可变绑定,不属于普通的全局对象属性。执行let window = undefined时,相当于在同一个声明式环境记录中重复声明已经存在的不可变绑定,直接触发规范的语法校验规则,抛出错误。
3. globalThis、Node环境global声明不报错的原因
- ES2020引入的
globalThis仅作为全局对象的可配置属性存在,不会被注入到全局声明式环境记录中 - Node环境的
global同样是全局对象的可配置属性,也没有被加入全局声明式环境记录 - 用
let声明这两个变量时,只是在声明式环境记录中新增了一个同名绑定,只会遮蔽全局对象上的原有属性,不存在重复声明已存在绑定的问题,因此不会触发报错。
内容的提问来源于stack exchange,提问作者zerdox
相关产品推荐
相关产品推荐

