在JavaScript中,全局执行上下文(Global Execution Context)是程序开始运行时创建的第一个执行上下文。每个执行上下文由三个重要部分组成:变量环境(Variable Environment)、词法环境(Lexical Environment)和 this 指向。下面详细解释变量环境和词法环境:
变量环境(Variable Environment)
变量环境是执行上下文的一个组成部分,它主要用于存储通过 var
关键字声明的变量和函数声明。变量环境具有以下特点:
- 变量提升:使用
var
声明的变量会被提升到当前作用域的顶部,并且会被初始化为undefined
。函数声明也会被提升,并且可以在声明之前调用。 - 不可变绑定:一旦变量环境中的变量被创建,它的绑定(即变量名和值的关联)在整个执行上下文的生命周期内是不可变的。
词法环境(Lexical Environment)
词法环境也是执行上下文的一部分,它主要用于存储通过 let
和 const
关键字声明的变量以及块级作用域的信息。词法环境具有以下特点:
- 块级作用域:
let
和const
声明的变量具有块级作用域,即它们只在声明它们的块(如if
语句、for
循环等)内可见。 - 暂时性死区(Temporal Dead Zone, TDZ):使用
let
和const
声明的变量不会被提升到当前作用域的顶部,而是存在于暂时性死区内。在变量声明之前访问这些变量会导致ReferenceError
。 - 可变绑定:词法环境中的变量绑定可以在块级作用域内被重新赋值(
let
),但const
声明的常量一旦赋值就不能再重新赋值。
示例代码
// 全局执行上下文开始
// 变量环境:存储 var 声明的变量和函数声明
var globalVar = 'This is a global variable';
function globalFunction() {
console.log('This is a global function');
}
// 词法环境:存储 let 和 const 声明的变量
let globalLet = 'This is a global let variable';
const globalConst = 'This is a global const variable';
// 变量提升示例
console.log(globalVar); // 输出: This is a global variable
console.log(globalFunction); // 输出: [Function: globalFunction]
// 暂时性死区示例
// console.log(globalLet); // 报错: ReferenceError: Cannot access 'globalLet' before initialization
// console.log(globalConst); // 报错: ReferenceError: Cannot access 'globalConst' before initialization
// 块级作用域示例
if (true) {
let blockLet = 'This is a block-scoped let variable';
const blockConst = 'This is a block-scoped const variable';
console.log(blockLet); // 输出: This is a block-scoped let variable
console.log(blockConst); // 输出: This is a block-scoped const variable
}
// console.log(blockLet); // 报错: ReferenceError: blockLet is not defined
// console.log(blockConst); // 报错: ReferenceError: blockConst is not defined
// 可变绑定示例
globalLet = 'New value for globalLet';
console.log(globalLet); // 输出: New value for globalLet
// globalConst = 'New value for globalConst'; // 报错: TypeError: Assignment to constant variable.
总结
- 变量环境:主要用于存储
var
声明的变量和函数声明,支持变量提升,绑定不可变。 - 词法环境:主要用于存储
let
和const
声明的变量,支持块级作用域和暂时性死区,绑定可变(let
)或不可变(const
)。