JavaScript词法作用域按变量定义位置静态确定查找链,函数创建时[[Environment]]即绑定外层环境,执行时严格沿该链逐级向上查找,不依赖调用位置;全局为终点,未找到则抛ReferenceError。

JavaScript 中词法作用域决定变量查找的方式,是看变量在代码中**定义的位置**,而不是它在哪里被调用。引擎在函数创建时就固定了它的“父级环境”,之后每次访问变量,都严格按这个静态链一层层往外找。
变量查找从当前作用域开始
执行到某行代码时,JS 引擎先在当前作用域(比如函数体、块级 {} 内)查找变量声明。没找到,就顺着函数定义时记录的 [[Environment]] 向上跳一级,进入外层词法环境。
- 这个过程不依赖调用方式,哪怕函数被传到别处执行,也还是查它原来定义时的外层作用域
- 例如:一个在
outer函数里定义的inner,无论在哪调用,都优先查outer里的变量,再查全局 - 不会跳过中间层,也不会跨分支去查同级函数的作用域
作用域链在函数定义时就确定
函数对象生成那一刻,内部属性 [[Environment]] 就已绑定其外层词法环境。这和执行时机无关——即使外层函数早已执行完毕,这条链依然存在。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
let/const声明的块级作用域也会被纳入链中(如if或for块),但只对其中声明的变量生效 -
var声明会提升到函数作用域顶部,所以它总出现在函数级 AO(活动对象)里,不影响链结构 - 全局作用域始终是链的终点;如果查到这儿还没找到,直接抛
ReferenceError,不是返回undefined
调试时可直观看到作用域链
在 Chrome DevTools 中设断点停住函数执行,右侧 “Scope” 面板会列出当前作用域及其上级词法环境,清晰展示变量实际能访问到哪些层级。
立即学习“Java免费学习笔记(深入)”;
- 每个层级显示对应变量对象(VO/AO)或词法环境记录
- 能看到
Closure条目——这就是闭包所捕获的外层变量 - 这是验证变量是否“真能访问”的最可靠方式,比靠经验猜测更准确
避免常见误解
词法作用域和 this 绑定、call/apply、甚至 typeof missing 的行为完全无关。后者是语言特例,绕过了常规查找流程。
-
console.log(missing)报错,而typeof missing返回"undefined",两者机制不同 -
with和eval会动态干扰作用域链,但现代代码应禁用它们 - 箭头函数没有自己的
this,但它照样遵循词法作用域查普通变量

















