Skip to content

二、变量声明:let 与 const

var 的问题

在 ES6 之前,JavaScript 中只有 var 一种变量声明方式,但它存在以下问题:

1. 变量提升

javascript
console.log(a); // undefined,而不是报错
var a = 10;

2. 重复声明

javascript
var a = 10;
var a = 20; // 不会报错,会覆盖之前的值
console.log(a); // 20

3. 作用域混乱

var 只有函数作用域,没有块级作用域:

javascript
if (true) {
  var b = 20;
}
console.log(b); // 20,在块外也能访问

let 声明变量

let 是 ES6 引入的新变量声明方式,解决了 var 的问题:

1. 块级作用域

javascript
if (true) {
  let c = 30;
}
console.log(c); // 报错:c is not defined

2. 不能重复声明

javascript
let d = 40;
let d = 50; // 报错:Identifier 'd' has already been declared

3. 不存在变量提升

javascript
console.log(e); // 报错:e is not defined
let e = 60;

const 声明常量

const 用于声明常量,即不可变的值:

1. 只读

javascript
const f = 70;
f = 80; // 报错:Assignment to constant variable.

2. 必须赋值

javascript
const g; // 报错:Missing initializer in const declaration

3. 引用类型可修改

对于引用类型(对象、数组),const 只保证引用地址不变,内部属性可以修改:

javascript
const obj = { name: 'ES6' };
obj.name = 'ES7'; // 可以修改
console.log(obj.name); // ES7

const arr = [1, 2, 3];
arr.push(4); // 可以修改
console.log(arr); // [1, 2, 3, 4]

let / const / var 三者区别总结

特性varletconst
作用域函数作用域块级作用域块级作用域
变量提升存在不存在不存在
重复声明允许不允许不允许
重新赋值允许允许不允许(引用类型内部可修改)
初始值可选可选必须

实战案例:块级作用域与循环问题

问题:使用 var 的循环变量泄露

javascript
for (var i = 0; i < 3; i++) {
  setTimeout(() => {
    console.log(i); // 输出 3, 3, 3
  }, 1000);
}

解决方案:使用 let

javascript
for (let i = 0; i < 3; i++) {
  setTimeout(() => {
    console.log(i); // 输出 0, 1, 2
  }, 1000);
}

解释

  • 使用 var 时,循环变量 i 是函数作用域,在循环结束后变为 3,所以三个 setTimeout 回调都输出 3
  • 使用 let 时,循环变量 i 是块级作用域,每次循环都会创建一个新的 i,所以输出 0, 1, 2

最佳实践

  1. 优先使用 const:对于不需要重新赋值的变量,使用 const
  2. 其次使用 let:对于需要重新赋值的变量,使用 let
  3. 尽量避免使用 var:var 存在诸多问题,在现代 JavaScript 中应尽量避免使用

通过本章节的学习,你已经掌握了 ES6 中变量声明的新方式。let 和 const 解决了 var 的许多问题,使代码更加安全和可维护。

© 2026 编程马·菜鸟教程 版权所有