Skip to content

1. 作用域

  • var:具有函数作用域或全局作用域。在块(如 if 语句或 for 循环)内声明的 var 变量实际上会被提升到函数作用域的顶部。
  • letconst:具有块级作用域。它们只在声明它们的块内有效,例如在 if 语句、for 循环或任何其他块 {} 中。

2. 重复声明

  • var:在同一作用域内可以重复声明同一个变量。
  • letconst:不允许在同一作用域内重复声明。

3. 变量提升

  • var:变量会被提升到其所在函数或全局作用域的顶部,但是初始化(赋值)不会提升。
  • letconst:不会提升到块的顶部,而是提升到块的开始。在声明之前访问它们会导致 ReferenceError,这个区域被称为“暂时性死区”。
js
// var
console.log(a);  // undefined
var a = 10;

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

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

4. 赋值和修改

  • varlet:可以被重新赋值和修改。
  • const:一旦声明并初始化后,其值不能被改变(对于基本数据类型)。如果 const 用于对象或数组,可以修改其属性或元素,但不能重新赋值。

5. 总结

let 与 var 的区别

  • let 不存在变量提升

    var 存在 变量提升 现象,即变量可以在声明之前使用,值为 undefined。let 或 const 所声明的变量一定要在声明后使用,否则报错。

  • let 不允许重复声明

    let 不允许在相同作用域内,重复声明同一个变量,重复声明报错。var 重复声明会覆盖或忽略。const 声明的常量,也与 let 一样不可重复声明。

  • let 不绑定全局作用域

    当在全局作用域中使用 var 声明的时候,会创建一个新的全局变量作为全局对象的属性。然而 let 和 const 不会。

  • let 存在暂时性死区现象

    在 let 和 const 声明变量之前,只要变量在还没有声明完成前使用,就会报错,都属于该变量的 暂时性死区。即,let 和 const 声明的变量不会被提升到作用域顶部,如果在声明之前访问这些变量,会导致报错。let 和 const 声明的变量会放在 TDZ 暂时性死区里面,访问暂时性死区的变量就会报错,且检测报错发生在词法解析(AST词法解析树)阶段,而不是在代码执行阶段。

  • let 会产生块级作用域

    let 或 const 只在声明所在的块级作用域内有效,即,块级作用域中有效。块级作用域的出现,实际上使得获得广泛应用的匿名立即执行函数表达式(匿名 IIFE)不再必要了。

let 与 const 的区别

  • const 声明一个只读的常量。一旦声明,常量的值就不能改变。

    const 声明的变量不得改变值,这意味着,const 一旦声明变量,就必须立即初始化,不能留到以后赋值。对于 const 来说,只声明不赋值,就会报错。const 声明不允许修改绑定,但允许修改值。这意味着当用 const 声明对象时,可以修改对象的属性值,只是不能修改对象在栈中的引用地址。

  • const 简单类型一旦声明就不能再更改,复杂类型(数组、对象等)指针指向的地址不能更改,内部数据可以更改。