JavaScript 中 var、let、const 的核心区别与实战应用
要理解 const、var、let 的区别,我们可以从 作用域、变量提升、可重复声明、可修改性 这几个核心维度展开。
一、核心概念铺垫
首先明确两个基础概念:
- 函数作用域:变量只在声明它的函数内部可访问(
var是函数作用域)。 - 块级作用域:变量只在声明它的
{}内部可访问(let/const是块级作用域,{}包括if/for/while/普通代码块)。 - 变量提升:JS 引擎在执行代码前,会把变量声明'提升'到当前作用域顶部(但赋值不会提升)。
二、逐个拆解与对比
1. var(ES5 语法)
var 是 ES5 中声明变量的方式,特性如下:
- 作用域:函数作用域(无块级作用域)。
- 变量提升:声明会被提升,且提升后默认值为
undefined。 - 可重复声明:同一作用域内可重复声明同一个变量,后声明的会覆盖前一个。
- 可修改:声明后可随意修改值。
// 1. 函数作用域(无块级作用域)
if (true) {
var a = 10;
}
console.log(a); // 输出 10(a 跳出了 if 的 {},因为 var 无块级作用域)
// 2. 变量提升
console.log(b); // 输出 undefined(声明提升了,赋值没提升)
var b = 20;
// 3. 可重复声明
var c = 30;
var c = 40;
console.log(c); // 输出 40(后声明的覆盖前一个)
// 4. 可修改
var d = 50;
d = 60;
console.log(d); // 输出 60
2. let(ES6 语法)
let 是 ES6 为解决 var 的缺陷新增的声明方式,特性如下:
- 作用域:块级作用域(被
{}限制)。 - 变量提升:存在'暂时性死区(TDZ)'——声明也会提升,但提升后不会赋值
undefined,在声明前访问会报错。 - 不可重复声明:同一作用域内不能重复声明同一个变量(包括不能和
var/const重复)。 - 可修改:声明后可修改值。
// 1. 块级作用域
if (true) {
let a = 10;
}
console.log(a); // 报错:a is not defined(a 被 if 的 {} 限制,外部访问不到)
// 2. 暂时性死区
console.log(b); // 报错:Cannot access 'b' before initialization
let b = 20;
// 3. 不可重复声明
let c = 30;
// let c = 40; // 报错:Identifier 'c' has already been declared
// var c = 40; // 同样报错
// 4. 可修改
let d = 50;
d = 60;
console.log(d); // 输出 60
3. const(ES6 语法)
const 用于声明常量,特性和 let 基本一致,核心区别是不可修改:
- 作用域:块级作用域(和
let完全一样)。 - 变量提升:同样有暂时性死区(和
let完全一样)。 - 不可重复声明:和
let完全一样。 - 不可修改:声明时必须赋值,且赋值后不能修改引用(注意:如果是对象/数组,内部属性/元素可修改)。
// 1. 块级作用域
if (true) {
const a = 10;
}
console.log(a); // 报错:a is not defined
// 2. 暂时性死区
console.log(b); // 报错:Cannot access 'b' before initialization
const b = 20;
// 3. 不可重复声明
const c = 30;
// const c = 40; // 报错
// 4. 声明时必须赋值
// const d; // 报错:Missing initializer in const declaration
// 5. 不可修改引用(重点)
const e = 50;
// e = 60; // 报错:Assignment to constant variable.
// 注意:对象/数组的内部可修改(只是引用不能变)
const obj = { name: "张三" };
obj.name = "李四"; // 正常执行,输出 { name: '李四' }
console.log(obj);
const arr = [1, 2];
arr.push(3); // 正常执行,输出 [1,2,3]
console.log(arr);
三、核心区别对比表
| 特性 | var | let | const |
|---|---|---|---|
| 作用域 | 函数作用域 | 块级作用域 | 块级作用域 |
| 变量提升 | 有(提升为 undefined) | 有(暂时性死区) | 有(暂时性死区) |
| 重复声明 | 允许 | 不允许 | 不允许 |
| 声明后赋值 | 允许(默认 undefined) | 允许(默认未初始化) | 不允许(必须立即赋值) |
| 修改值 | 允许 | 允许 | 引用不可改(对象/数组内部可改) |
四、实际开发中的使用建议
- 优先用
const:声明不需要修改的变量(如常量、固定引用的对象/数组),能减少代码意外修改的风险。 - 其次用
let:声明需要修改的变量(如循环变量、状态变量)。 - 完全不用
var:var的函数作用域和变量提升容易导致 bug(比如循环变量泄露、重复声明覆盖),ES6 后已被let/const替代。
1. const 的使用场景
适合以下所有'不需要修改值/引用'的场景:
- 声明常量:数学常量、配置项、固定字符串等。
// 数学常量
const PI = 3.1415926;
const RADIUS = 5;
const AREA = PI * RADIUS * RADIUS;
// 配置项
const BASE_URL = 'https://api.example.com';
const TOKEN = 'abc123456';
// 固定字符串
const TITLE = '个人信息';
- 声明不需要重新赋值的对象/数组:
const只是限制'引用不可变',对象/数组的内部属性/元素可以修改。
// 用户信息对象
const userInfo = { name: 'User', class: 'Class 24', hobby: ['唱歌', '跳舞'] };
userInfo.name = 'New Name';
userInfo.hobby.push('爬山');
// 列表数据
const list = ['苹果', '香蕉'];
list.push('橙子');
- 声明 DOM 元素:创建后只会修改文本/样式,不会重新赋值成另一个元素。
const h2 = document.createElement('h2');
h2.textContent = '个人信息';
document.body.appendChild(h2);
const btn = document.createElement('button');
btn.textContent = '点击';
document.body.appendChild(btn);
2. let 的使用场景
只有当你需要'修改变量的值/引用'时,才用 let:
- 循环变量:
for/while循环中的计数器。
const info = ['班级', '学号', '姓名'];
for (let i = 0; i < info.length; i++) {
const p = document.createElement('p');
p.textContent = info[i];
document.body.appendChild(p);
}
let count = 0;
while (count < 3) {
console.log('计数:', count);
count++;
}
- 状态变量:开关状态、计数器、表单输入值等。
let isShow = false;
const btn = document.createElement('button');
btn.textContent = '显示/隐藏';
btn.onclick = function() {
isShow = !isShow;
console.log('状态:', isShow);
};
document.body.appendChild(btn);
let num = 0;
const countBtn = document.createElement('button');
countBtn.textContent = '计数';
countBtn.onclick = function() {
num++;
countBtn.textContent = `计数:${num}`;
};
document.body.appendChild(countBtn);
- 临时变量:分步计算的值、条件判断后需要修改的变量。
let total = 0;
total += 10;
total *= 0.8;
console.log('总价:', total);
let message;
const isLogin = false;
if (isLogin) {
message = '欢迎登录';
} else {
message = '请先登录';
}
五、避坑提醒
- ❌ 错误:用
const声明需要修改的变量
const i = 0;
i++; // 报错:Assignment to constant variable.
- ❌ 错误:没必要用
let声明不修改的变量
// 标题文本不会改,应该用 const 而不是 let
let TITLE = '个人信息'; // 应改为 const
六、总结
- 优先用
const:所有不需要重新赋值的场景,用const能让代码更安全、语义更清晰。 - 仅用
let:只有当变量需要重新赋值时,才用let。 - 核心原则:能不用
let就不用,用const约束'不变',用let表示'可变',彻底抛弃var。


