词法环境通过环境记录存储变量绑定、outer引用构建作用域链,静态确定结构并在执行时构建;环境记录分声明式(let/const/函数)、对象式(with)、全局式三种类型,变量查找只沿outer链在环境记录中进行。

JavaScript 中词法环境记录变量标识符的绑定关系,靠的是环境记录(Environment Record) 和 外部词法环境引用(outer) 这两个核心部分协同工作。它不是靠“扫描代码”或“运行时动态推断”,而是在函数/块定义时就静态确定结构,并在执行上下文创建时真实构建出数据结构。
词法环境用环境记录存绑定
环境记录是词法环境的“存储层”,专门负责把标识符(比如 let x、const y、function z())和它们对应的值或状态关联起来。它分几种类型,对应不同声明方式:
-
声明式环境记录(Declarative Record):用于
let、const、函数声明、参数等。每个绑定都有明确的状态(未初始化 / 已初始化 / 已赋值),支持 TDZ(暂时性死区)。 -
对象式环境记录(Object Record):仅用于
with语句,把标识符映射到某个对象的属性上(已不推荐使用)。 -
全局环境记录(Global Record):挂载在全局对象(如
window或globalThis)上,同时管理var声明和顶层let/const,但行为有差异。
例如:
function foo() {
let a = 1;
const b = 2;
var c = 3;
}
进入 foo 执行时:
- 词法环境的环境记录中会为
a和b创建条目,初始状态为“未初始化”(TDZ); -
c虽然也出现在词法环境记录里,但它同时存在于变量环境中,且初始化为undefined。
外部引用构成作用域链
每个词法环境都带一个 outer 属性,指向其词法嵌套外层的词法环境(不是调用栈上的上层!)。这个引用链就是作用域链的物理基础。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
比如闭包场景:
function outer() {
let x = 10;
return function inner() {
console.log(x); // 查找 x:inner 环境记录 → outer 环境记录 → 全局
};
}
inner 的词法环境 outer 字段指向 outer 的词法环境,所以能访问 x。这个链在函数定义时就固定了,与 inner 在哪被调用无关。
不同声明方式进入词法环境的方式不同
-
let/const:只写入词法环境的声明式记录,不进变量环境;声明前访问抛ReferenceError(TDZ)。 -
var:既写入词法环境,也写入变量环境;变量环境在执行开始前就初始化为undefined,所以可“提升”访问。 - 函数声明:在词法环境中创建绑定,且在变量环境中也存在(兼容旧行为);提升后可调用。
- 参数:直接写入当前函数词法环境的声明式记录,形参名与实参值绑定。
查找变量时只走词法环境链
引擎查找变量时,始终从当前词法环境的环境记录开始,找不到就顺着 outer 往上找,直到全局环境。它不查变量环境——变量环境只是为 var 提供初始化兼容的“后备机制”,最终所有访问都落在词法环境链上。
简单说:
✅ 词法环境是变量查找的唯一路径;
✅ 环境记录是绑定存放地;
✅ outer 是通往父级作用域的指针;
✅ let/const/var/func 的差别,本质是它们何时、以什么状态写入环境记录。
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










