JavaScript作用域链基于函数定义时的词法环境逐级回溯,由[[Environment]]内部槽固化;查找变量时从当前环境开始向上匹配,直至全局,未找到则报ReferenceError;闭包因此使外层变量持久化。

JavaScript 的作用域链在嵌套函数中向上查找变量,本质是沿着函数定义时所在的词法作用域逐级回溯,而不是按函数调用时的执行位置。
作用域链基于函数定义时的嵌套结构
每个函数在创建时,引擎会记录它被定义时所处的词法环境(即外层作用域),这个链接关系在函数对象内部的 [[Environment]] 内部槽中固化。无论函数后来在哪里被调用,都沿这个“定义时”的链向上找。
- 全局函数 → 全局作用域
- 函数 A 中定义函数 B → B 的外部引用指向 A 的活动对象(或词法环境)
- A 中定义 B,B 中定义 C → C 的外部引用指向 B 的环境,B 的外部引用指向 A 的环境
查找过程:从当前作用域开始,逐级向上匹配
当访问一个变量(如 name)时,JS 引擎按以下顺序搜索:
- 先查当前函数自身的词法环境(形参、let/const 声明、function 声明)
- 没找到,就查该函数的 [[Environment]] 指向的外层环境
- 继续向上,直到全局作用域;若全局也找不到,则报 ReferenceError
例如:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
function outer() {const x = 10;
function inner() {
console.log(x); // 查找:inner 环境 → outer 环境(找到 x=10)
}
inner();
}
闭包让外层变量“活”下来
即使外层函数已执行完毕,只要内层函数还存在(比如作为返回值或被引用),其 [[Environment]] 仍保留对原外层词法环境的引用,变量不会被回收。
- 这正是闭包的核心机制:内层函数“记住”了它定义时的外层变量
- 多个内层函数共享同一个外层环境(比如循环中创建多个函数,若不加处理,可能共用同一个变量绑定)
注意:var 和 let/const 在作用域链中的表现一致,但绑定时机不同
查找逻辑一样,都是沿作用域链向上;区别在于:
- var 声明会被提升并初始化为 undefined,存在于函数作用域顶部
- let/const 声明有暂时性死区(TDZ),虽也在作用域链中,但在声明前访问会报 ReferenceError,不是找不到,而是不可访问

















