词法环境管理let/const和块级作用域,支持TDZ与闭包;变量环境处理var和函数声明,实现变量提升。二者同属执行上下文,但生命周期与设计目的不同:前者动态构建作用域链,后者在创建阶段静态初始化。

词法环境和变量环境都是执行上下文的内部组成部分,但它们分工明确、行为不同:词法环境管 let/const 和块级作用域,变量环境管 var 和函数声明。
词法环境负责块级作用域和暂时性死区
词法环境包含一个环境记录(Environment Record)和一个指向外部词法环境的引用(Outer Lexical Environment Reference),构成作用域链。它在代码执行过程中动态创建和销毁——比如进入一个 {} 块、if 或 for 语句时,就会生成新的词法环境。
-
let和const声明绑定在词法环境中,不会被提升,访问前会触发“暂时性死区”(TDZ)报错 - 函数内部的参数也存放在词法环境里,与
let同级处理,所以不能用let重复声明同名参数 - 闭包的本质,就是内层函数保留了对外层词法环境的引用
变量环境只处理 var 和函数声明
变量环境本质上是一个特殊的词法环境,但它在执行上下文创建阶段就完成初始化,之后基本不再变化。它的设计目标是支持“变量提升”这一历史行为。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
var声明在编译阶段就被加入变量环境,初始值为undefined - 函数声明也会被完整提升到变量环境中,且优先级高于同名
var - 变量环境不响应块级作用域——
if块里的var仍属于外层函数或全局环境
全局上下文中两者常指向同一对象
出于实现优化考虑,JavaScript 引擎在全局执行上下文中通常让词法环境和变量环境引用同一个环境记录对象。这意味着全局的 var、let、const 和函数声明,看起来都“在同一个地方”,但底层逻辑依然分离:前者走变量环境路径,后者走词法环境路径。
立即学习“Java免费学习笔记(深入)”;
- 这种合并只发生在全局上下文;函数上下文中,两者是独立对象
- 即便指向同一对象,
let仍受 TDZ 约束,var仍可提前访问(值为undefined)
本质区别在于设计目的和生命周期
变量环境是为兼容 ES5 及更早行为而设的“静态快照”,关注声明存在性;词法环境是为精确表达作用域语义而设的“动态结构”,关注变量何时可访问、在哪一层生效。
- 变量提升(hoisting)现象,根源在变量环境的早期绑定
- 块级作用域、TDZ、闭包,都依赖词法环境的层级引用机制
- 二者共同协作,才让 JavaScript 既能向后兼容,又能支持现代语法特性

















