var / let / const 全面对比
核心区别总结
| 特性 | var |
let |
const |
|---|---|---|---|
| 作用域 | 函数作用域 | 块级作用域 | 块级作用域 |
| 变量提升 | 提升并初始化undefined |
提升但不初始化(TDZ) | 提升但不初始化(TDZ) |
| 重复声明 | 允许 | 禁止 | 禁止 |
| 全局绑定 | 成为window属性 |
不成为window属性 |
不成为window属性 |
| 初始值 | 可不初始化 | 可不初始化 | 必须初始化 |
| 循环中的表现 | 每次循环共享同一变量 | 每次迭代创建新绑定 | 每次迭代创建新绑定 |
关键概念详解
1. 块级作用域(Block Scope)
let和const声明的变量只在代码块{}内有效:
1 | { |
2. 暂时性死区(TDZ - Temporal Dead Zone)
在声明前访问let/const变量会触发错误(而var返回undefined):
1 | console.log(a); // undefined(变量提升) |
TDZ 本质:
从进入作用域到变量声明之间的区域,禁止访问变量
3. const 的特殊行为
1 | const a = {}; |
const 本质:
- 保证变量指向的内存地址不变(对于对象是堆地址,对于基本类型是栈值)
- 对象属性修改不受限制(除非使用
Object.freeze)
最佳实践指南
**默认使用
const**
除非需要重新赋值,否则优先用const(减少意外修改)1
2const API_URL = "https://api.example.com";
const config = { timeout: 5000 };**需要重新赋值时用
let**
替代var的所有场景1
2let count = 0;
count = processItems(items);**避免使用
var**
除特殊兼容场景外不应使用const 对象保护技巧
1
2
3
4
5
6
7
8
9
10// 深度冻结对象
const deepFreeze = obj => {
Object.freeze(obj);
Object.keys(obj).forEach(key => {
if (typeof obj[key] === 'object') deepFreeze(obj[key]);
});
};
const safeObj = deepFreeze({ nested: { value: 1 } });
safeObj.nested.value = 2; // ❌ 严格模式报错
常见误区
1 | // 误区1:const不能修改对象 |
浏览器兼容性
let/const:ES6+(现代浏览器全支持,IE11部分支持)- 旧环境需通过Babel转译为ES5
1 |