在 JavaScript 中,词法环境(Lexical Environment) 是 JavaScript 解释器在执行代码时创建的一种内部数据结构,用于存储变量和函数的作用域信息。
一个词法环境由两个主要部分组成:
- 环境记录(Environment Record)
- 记录变量、函数等标识符的绑定。
- 外部环境引用(Outer Environment Reference)
- 指向外部词法环境(即上层作用域),用于实现作用域链。
1. 环境记录(Environment Record)
环境记录存储变量和函数声明,不同类型的环境记录有不同的存储方式:
-
声明式环境记录(Declarative Environment Record)
- 用于存储
let
、const
、function
声明的变量。 - 例如在函数作用域或块级作用域内,变量会存储在此环境记录中。
- 用于存储
-
对象环境记录(Object Environment Record)
- 主要用于
var
声明的变量,它们会被存储在全局对象(如window
或globalThis
)中。 - 例如,全局作用域的
var
变量和function
声明会挂载到全局对象上。
- 主要用于
示例:
var globalVar = 1; // 存在于对象环境记录中(window.globalVar)
let blockVar = 2; // 存在于声明式环境记录中
const blockConst = 3; // 存在于声明式环境记录中
function test() {} // 存在于对象环境记录(在 `var` 方式下)或声明式环境记录(在 `let/const` 方式下)
2. 外部环境引用(Outer Environment Reference)词法环境-outer
- 用于指向外部(上层)词法环境,形成作用域链(Scope Chain)。
- 作用域链的查找是逐层向上查找,直到全局作用域。
示例:
function outer() {
let a = 10;
function inner() {
let b = 20;
console.log(a + b); // `inner` 作用域的词法环境会引用 `outer` 作用域
}
inner();
}
outer();
在 inner
函数的词法环境中:
- 环境记录:存储
b
- 外部环境引用:指向
outer
作用域的词法环境,其中存储a
- 作用域链:
inner
→outer
→全局
词法环境的类型
- 全局环境(Global Lexical Environment)
- 最顶层的环境,变量存储在全局对象上(如
window
)。
- 最顶层的环境,变量存储在全局对象上(如
- 函数环境(Function Lexical Environment)
- 每个函数调用都会创建新的词法环境,存储参数、局部变量等。
- 块级环境(Block Lexical Environment)
let
、const
变量会在块级作用域({}
内)创建一个新的词法环境。
示例:
let x = 10; // 全局环境
function foo() {
let y = 20; // 函数环境
if (true) {
let z = 30; // 块级环境
}
}
foo();
总结
词法环境的属性 | 作用 |
---|---|
环境记录 | 存储变量、函数等标识符的绑定 |
外部环境引用 | 指向外部作用域,形成作用域链 |
全局环境 | 作用域最顶层 |
函数环境 | 每个函数调用都会创建新的词法环境 |
块级环境 | let 和 const 形成的局部作用域 |
这就是 JavaScript 词法环境的核心概念,它是 JS 作用域和闭包的基础。