词法环境是javascript中变量查找的核心机制,静态绑定于函数定义时,由环境记录和外部环境引用组成,形成向上委托的链式结构,实现闭包的层级继承。

词法环境是 JavaScript 中决定变量在哪里被查找的核心机制。它不是运行时动态生成的,而是在函数定义那一刻就静态绑定好的——这个静态性,正是理解嵌套闭包中“层级继承”的关键。
词法环境由两部分组成
每个词法环境包含:
-
环境记录(Environment Record):实际存储变量、函数声明的地方,比如
let count = 0就存在这里; - 外部环境引用(outer reference):指向其外层词法环境的指针,形成一条向上的链路。
这条链路不是调用时才连上的,而是函数对象创建时就写死在内部属性 [[Environment]] 里的。
嵌套函数如何继承词法环境
看这个例子:
function a() {
let x = 1;
function b() {
let y = 2;
function c() {
console.log(x, y); // ✅ 可访问
}
return c;
}
return b();
}
执行过程对应词法环境链:
-
c的[[Environment]]指向b创建时的词法环境(含y和对a环境的outer引用); -
b的[[Environment]]指向a创建时的词法环境(含x和对全局环境的outer引用); - 所以
c查找x时,先查自己环境(无),再顺着outer到b环境(仍无),再顺着b的outer到a环境(找到x)。
这就是“层级继承”——不是复制值,而是逐层向上委托查找。
变量捕获只发生在被引用时
词法环境整条链不会全被保留。引擎只会把**被闭包实际读写过的变量**保留在堆中:
- 如果
c只用了x,没碰y,那么y在b执行完后仍可能被回收(现代引擎如 V8 会做优化); - 但只要
c引用了x,a的整个词法环境(至少含x的那部分)就会因c的[[Environment]]而持续存活; - 这种“按需保留”说明:闭包不是把外层环境整个拷贝一份,而是建立了一条可追溯、可访问的引用路径。
多层嵌套中,this 和 arguments 不参与继承
词法环境只管 let/const/var 声明和函数声明。它不包含:
-
this值——由调用方式决定,与词法环境无关; -
arguments对象——属于调用时的执行上下文,不是词法环境的一部分; - 函数参数(
function f(p) { }中的p)则属于当前函数的环境记录,会被正常捕获。
也就是说,闭包能“记住”的,仅限于词法作用域内声明的标识符,不包括运行时动态绑定的内容。










