摘要:JavaScript中的变量声明方式var
、let
和const
有什么区别?本文从作用域、提升、重复声明等角度详细解析,并给出实际开发中的使用建议。
1. 引言
在JavaScript中,变量声明是基础中的基础。ES6之前,我们只有var
;ES6引入了let
和const
,它们解决了var
的一些设计缺陷。本文将深入对比这三种声明方式,帮助开发者避免常见陷阱。
2. 核心区别
2.1 作用域(Scope)
var
:函数级作用域function test() { var a = 10; if (true) { var a = 20; // 同一个变量 } console.log(a); // 输出20 }
let/const
:块级作用域({}
内有效)if (true) { let b = 30; const c = 40; } console.log(b); // 报错:b is not defined
为什么需要块级作用域?
避免循环变量泄露、防止意外覆盖变量(参考freecodecamp.org)。
2.2 变量提升(Hoisting)
var
:声明提升,值为undefined
console.log(x); // undefined var x = 5;
let/const
:存在暂时性死区(TDZ)console.log(y); // 报错:Cannot access 'y' before initialization let y = 10;
TDZ的本质:
从作用域开始到声明语句之间的区域,禁止访问未初始化的变量。
2.3 重复声明
var
:允许重复声明(易导致bug)var z = 1; var z = 2; // 合法但危险
let/const
:禁止重复声明let w = 1; let w = 2; // 报错:Identifier 'w' has already been declared
2.4 可变性
声明方式 | 是否需要初始值 | 是否可重新赋值 |
---|---|---|
var | 否 | 是 |
let | 否 | 是 |
const | 是 | 否(但对象属性可修改) |
const obj = { name: "Alice" };
obj.name = "Bob"; // 合法
obj = {}; // 报错
注意:
const
保证的是变量指向的内存地址不变,而非值不变(参考devpoint.cn)。
3. 为什么推荐使用let/const?
-
避免意外全局变量
for (var i = 0; i < 10; i++) { /*...*/ } console.log(i); // 10(泄露到全局) for (let j = 0; j < 10; j++) { /*...*/ } console.log(j); // 报错
-
更严格的错误检查
let/const
的TDZ和禁止重复声明能提前发现编码错误。 -
代码可读性
const
明确标识常量,let
标识可变变量。
4. 使用建议
- 默认使用
const
:除非需要重新赋值。 - 需要变量时用
let
:替代var
的所有场景。 - 避免使用
var
:仅限旧代码维护。
性能注意:现代JS引擎对
let/const
的优化已与var
无异(参考youkuaiyun.com)。
5. 常见面试题
Q1:以下代码输出什么?
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
// 输出:3 3 3(var无块级作用域)
Q2:如何用let
修复上述问题?
for (let j = 0; j < 3; j++) {
setTimeout(() => console.log(j), 100);
}
// 输出:0 1 2
6. 总结
特性 | var | let | const |
---|---|---|---|
作用域 | 函数级 | 块级 | 块级 |
提升 | 是 | TDZ | TDZ |
重复声明 | 允许 | 禁止 | 禁止 |
典型用途 | 旧代码 | 循环/变量 | 常量/配置 |
最佳实践:拥抱ES6,用const
和let
写出更健壮的代码!
参考资料:
希望这篇博客能帮助到大家! 🚀