JavaScript全局变量访问的查找顺序及绑定位置机制探究
全局作用域中var/let声明的变量绑定差异
在全局作用域中使用var声明的变量和函数,既可以通过variable_name访问,也可以通过window.variable_name访问。
var foo = "10"; let bar= "20"; function func(){ } console.log(foo); //10 console.log(window.foo); //10
已明确的绑定规则
var foo:标识符foo的绑定由全局执行上下文 > Realm > 全局环境记录的对象记录(Object Record) 创建并维护。let bar:标识符bar的绑定由全局执行上下文 > 词法环境(LexicalEnvironment) > 全局环境记录的声明式记录(Declarative Record) 创建并维护。
变量访问的优先级与绑定判定逻辑
问题
当JavaScript在全局代码中访问变量X时,是否会优先检查全局环境记录的对象记录,再检查声明式记录?JavaScript是如何确定变量X的绑定所属记录的?
回答
JavaScript在全局环境中查找标识符时,会优先检查声明式记录(Declarative Record),再检查对象记录(Object Record),具体逻辑如下:
- 全局环境记录是复合结构,同时包含声明式记录和对象记录两个部分。
- 标识符解析时,引擎首先在声明式记录中查找匹配绑定——这里存储
let、const、class等声明的全局标识符。 - 若声明式记录中无匹配项,才会去对象记录中查找——这里存储
var声明的全局变量、全局函数,以及挂载到window对象上的属性。 - 若两边均无匹配,读取操作会抛出
ReferenceError;非严格模式下的隐式全局变量赋值,会自动在对象记录中创建对应属性。
注:实际代码中不允许let和var重复声明同名变量(会直接报错),但从规则逻辑上,声明式记录的绑定拥有更高优先级。
内容的提问来源于stack exchange,提问作者sql_dummy
相关产品推荐
相关产品推荐

