返回

探索 JavaScript 中 var、let 和 const 的本质区别

前端

在 JavaScript 中,变量声明是一个基础且重要的概念。理解 varletconst 之间的区别,有助于我们编写更高效、更安全的代码。本文将深入探讨这三个关键字的作用域规则、重复声明/重复赋值、变量提升和暂时死区等方面的差异,并提供相应的解决方案。

作用域规则

var

var 声明的变量具有函数作用域或全局作用域。这意味着在函数内部声明的 var 变量可以在整个函数内部访问,而在函数外部声明的 var 变量则成为全局变量,可以在整个模块中访问。

function exampleVar() {
    if (true) {
        var x = 10;
    }
    console.log(x); // 输出 10
}
exampleVar();

let

let 声明的变量具有块级作用域。块级作用域变量只能在声明它们的块级作用域内访问,例如在 if 语句块、for 循环或 while 循环内部。

function exampleLet() {
    if (true) {
        let y = 20;
    }
    console.log(y); // 报错:y is not defined
}
exampleLet();

const

const 声明的变量同样具有块级作用域,并且是只读的。这意味着一旦声明,const 变量就不能被重新赋值。

function exampleConst() {
    if (true) {
        const z = 30;
    }
    console.log(z); // 报错:z is not defined
}
exampleConst();

重复声明/重复赋值

var

var 允许在同一作用域内重复声明和重复赋值。

function exampleVarRe declaration() {
    var a = 1;
    var a = 2; // 允许
    console.log(a); // 输出 2
}
exampleVarRe declaration();

let

let 不允许在同一作用域内重复声明,但允许重复赋值。

function exampleLetRe declaration() {
    let b = 1;
    let b = 2; // 允许
    console.log(b); // 输出 2
}
exampleLetRe declaration();

const

const 既不允许重复声明,也不允许重复赋值。

function exampleConstRe declaration() {
    const c = 1;
    const c = 2; // 报错:Assignment to constant variable.
    console.log(c); // 报错:Assignment to constant variable.
}
exampleConstRe declaration();

变量提升

var

var 声明的变量会发生变量提升,即在代码执行之前,变量被提升到作用域的顶部。

function exampleVarHoisting() {
    console.log(a); // 输出 undefined
    var a = 1;
}
exampleVarHoisting();

let 和 const

letconst 声明的变量不会发生变量提升。在变量声明之前访问这些变量会导致引用错误(ReferenceError)。

function exampleLetHoisting() {
    console.log(b); // 报错:ReferenceError: Cannot access 'b' before initialization
    let b = 1;
}
exampleLetHoisting();

console.log(c); // 报错:ReferenceError: Cannot access 'c' before initialization
const c = 1;

暂时死区(TDZ)

var

var 声明的变量没有暂时死区。

function exampleVarTDZ() {
    console.log(d); // 输出 undefined
    var d = 1;
}
exampleVarTDZ();

let 和 const

letconst 声明的变量有暂时死区,在暂时死区内,变量是不可访问的。

function exampleLetTDZ() {
    console.log(e); // 报错:ReferenceError: Cannot access 'e' before initialization
    let e = 1;
}

function exampleConstTDZ() {
    console.log(f); // 报错:ReferenceError: Cannot access 'f' before initialization
    const f = 1;
}
exampleLetTDZ();
exampleConstTDZ();

综合比较

特性 var let const
作用域 全局或函数级 块级 块级
重复声明 允许 允许(但不允许重复赋值) 不允许
重复赋值 允许 不允许 不允许
变量提升 发生变量提升 不发生变量提升 不发生变量提升
暂时死区 没有暂时死区 有暂时死区 有暂时死区

何时使用 var、let 和 const

在实际开发中,应该根据不同的情况选择使用 varletconst 关键字。一般来说:

  • 如果需要声明一个全局变量或函数级变量,可以使用 var 关键字。
  • 如果需要声明一个块级作用域变量,可以使用 let 关键字。
  • 如果需要声明一个只读的块级作用域变量,可以使用 const 关键字。

更多资源

总结

varletconst 都是 JavaScript 中用于声明变量的关键字,但它们之间存在着本质区别。理解这些区别有助于我们编写更高效、更安全的代码。在实际开发中,应根据具体需求选择合适的声明方式,并遵循最佳实践。