var、let、const 区别

Aug 15 · 3 min

本文来介绍一下面试常问的 varletconst 有什么区别

#1. 作用域不同

var 没有块级作用域,letconst块级作用域var 声明变量:

for (var i = 0; i < 3; i++) {
  console.log(`循环内i的值:${i}`)
}
console.log(`循环外i的值:${i}`)
js

运行结果:

循环内 i 的值:0
循环内 i 的值:1
循环内 i 的值:2
循环外 i 的值:3

let 声明变量:

for (let i = 0; i < 3; i++) {
  console.log(`循环内i的值:${i}`)
}
console.log(`循环外i的值:${i}`)
js

运行结果:

循环内 i 的值:0
循环内 i 的值:1
循环内 i 的值:2
Uncaught ReferenceError: i is not defined

#2. 暂时性死区

只要使用了 let 和 const 声明的变量就会绑定这个块级作用域,不受外部影响
使用 var 来声明变量:

var a = 10
if (true) {
  console.log(a) // 10
  var a = 20
}
js

使用 let 声明变量:

var a = 10
if (true) {
  console.log(a)
  let a = 20
  // 报错:Uncaught ReferenceError: Cannot access 'a' before initialization
}
js

使用 const 声明变量:

var a = 10
if (true) {
  console.log(a)
  const a = 20
  // 报错:Uncaught ReferenceError: Cannot access 'a' before initialization
}
js

#3. 变量提升

var 声明的变量存在变量提升, 关于 let 变量提升文章在这里

#4. 重复声明

var 声明的变量可以重复声明, letconst 声明的不可以重复声明

var a = 10
var a = 20
console.log(a) // 20
js
var a = 10
let a = 20
// const a = 20
console.log(a)
// 报错:Uncaught SyntaxError: Identifier 'a' has already been declared
js

#5. 变量能否被修改

varlet 声明的变量可以修改,但 const 声明的常量不能修改

var a = 10  || let a = 10
a = 20
console.log(a) // 20
js
const a = 10
a = 20
console.log(a)
// 报错:Uncaught TypeError: Assignment to constant variable
js

#6. 垃圾回收

ES6 增加这两个关键字不仅有助于改善代码风格,而且同样有助于改进垃圾回收的过程。因为 constlet 都以块(而非函数)为作用域,所以相比于使用 var ,使用这两个新关键字可能会更早地让垃圾回收程序介入,尽早回收应该回收的内存。在块作用域比函数作用域更早终止的情况下,这就有可能发生。