在JavaScript中,全局执行上下文(Global Execution Context)是程序开始运行时创建的第一个执行上下文。每个执行上下文由三个重要部分组成:变量环境(Variable Environment)、词法环境(Lexical Environment)和 this 指向。下面详细解释变量环境和词法环境:

变量环境(Variable Environment)

变量环境是执行上下文的一个组成部分,它主要用于存储通过 var 关键字声明的变量和函数声明。变量环境具有以下特点:

  • 变量提升:使用 var 声明的变量会被提升到当前作用域的顶部,并且会被初始化为 undefined。函数声明也会被提升,并且可以在声明之前调用。
  • 不可变绑定:一旦变量环境中的变量被创建,它的绑定(即变量名和值的关联)在整个执行上下文的生命周期内是不可变的。

词法环境(Lexical Environment)

词法环境也是执行上下文的一部分,它主要用于存储通过 letconst 关键字声明的变量以及块级作用域的信息。词法环境具有以下特点:

  • 块级作用域letconst 声明的变量具有块级作用域,即它们只在声明它们的块(如 if 语句、for 循环等)内可见。
  • 暂时性死区(Temporal Dead Zone, TDZ):使用 letconst 声明的变量不会被提升到当前作用域的顶部,而是存在于暂时性死区内。在变量声明之前访问这些变量会导致 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 声明的变量和函数声明,支持变量提升,绑定不可变。
  • 词法环境:主要用于存储 letconst 声明的变量,支持块级作用域和暂时性死区,绑定可变(let)或不可变(const)。