JavaScript变量查找遵循就近原则,沿词法作用域链从当前执行上下文逐级向上搜索至全局,未找到则抛ReferenceError;作用域链静态确定于函数定义时,与调用位置无关。

JavaScript 中变量访问依赖作用域链,核心是“就近原则”:从当前执行上下文的作用域开始查找,逐级向上(词法嵌套层级)搜索,直到全局作用域;找不到则报 ReferenceError。
作用域链的形成基于词法作用域,不是调用位置
函数创建时,其内部就静态确定了外层词法环境(即外层函数或全局作用域),这个引用链就是作用域链。它与函数在哪被调用无关。
- 例如:内层函数即使作为参数传到其他地方执行,仍沿原定义位置的外层作用域查找变量
- 闭包的本质就是内层函数保留了对外层作用域链的引用
变量查找过程:从活动对象(AO)/词法环境(LE)开始向上遍历
每次函数执行时,会创建执行上下文,其中包含自己的词法环境(含局部变量、参数、函数声明),并指向外层词法环境。查找变量时:
- 先在当前词法环境的绑定对象(如函数的 AO 或块级环境记录)中找
- 没找到,就去
outer指向的上一级词法环境中找 - 持续向上,直到全局词法环境(浏览器中是
window或globalThis) - 全局也没找到 → 抛出
ReferenceError
注意 var、let/const 和 function 声明对作用域链的影响
它们都参与作用域链构建,但初始化时机和提升行为不同,影响“能否访问”和“访问到什么值”:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
立即学习“Java免费学习笔记(深入)”;
-
var声明会被提升并初始化为undefined,所在函数作用域内任何位置都可访问(但可能不是预期值) -
let/const声明也会提升,但存在“暂时性死区”(TDZ):从块开头到声明语句前,访问会直接报错,不进入作用域链查找阶段 -
function声明完整提升(声明 + 赋值),优先级高于var和let
调试技巧:用 console.dir(function) 查看 [[Scopes]]
在 Chrome DevTools 中,执行 console.dir(myFunc),展开输出,在 [[Scopes]] 属性里能看到该函数的作用域链结构,清晰显示每个层级的变量对象和闭包捕获的变量。
这是验证变量是否在作用域链中、理解闭包捕获逻辑最直接的方式。

















