let和const定义的变量在JavaScript预编译过程中与var的区别

90 阅读2分钟

在JavaScript预编译过程中,letconst 定义的变量与 var 有几个关键区别。

变量提升

  • var:声明会被提升到作用域顶部,并初始化为 undefined
  • letconst:声明也会被提升到作用域顶部,但不会初始化为 undefined。在实际执行到声明语句之前,变量处于暂时性死区(Temporal Dead Zone, TDZ),访问会导致 ReferenceError

初始化和暂时性死区(TDZ)

  • var:在预编译阶段,变量会被提升并初始化为 undefined

    console.log(a); // 输出: undefined
    var a = 10;
    
  • letconst:在预编译阶段,变量会被提升但不会初始化。在进入声明语句之前,变量处于暂时性死区(TDZ)。

    console.log(b); // ReferenceError: Cannot access 'b' before initialization
    let b = 10;
    
    console.log(c); // ReferenceError: Cannot access 'c' before initialization
    const c = 10;
    

作用域

  • var:函数作用域或全局作用域。声明的变量在整个函数或全局范围内可用,即使在块级代码(如iffor)中也是如此。

    if (true) {
        var d = 20;
    }
    console.log(d); // 输出: 20
    
  • letconst:块级作用域。变量仅在声明的块级代码内可用。

    if (true) {
        let e = 20;
        const f = 30;
    }
    console.log(e); // ReferenceError: e is not defined
    console.log(f); // ReferenceError: f is not defined
    

重复声明

  • var:允许在同一作用域内重复声明同一变量,但可能导致意外行为。

    var g = 10;
    var g = 20;
    console.log(g); // 输出: 20
    
  • letconst:不允许在同一作用域内重复声明同一变量,会导致语法错误。

    let h = 10;
    let h = 20; // SyntaxError: Identifier 'h' has already been declared
    
    const i = 10;
    const i = 20; // SyntaxError: Identifier 'i' has already been declared
    

总结

  • 提升var 声明的变量会被提升并初始化为 undefinedletconst 声明的变量会被提升但不会初始化。
  • 暂时性死区(TDZ)letconst 声明的变量在实际声明前不可访问,会导致 ReferenceError
  • 作用域var 是函数作用域或全局作用域;letconst 是块级作用域。
  • 重复声明var 允许重复声明;letconst 不允许在同一作用域内重复声明。