优先使用const,只有需要重新赋值时用let。
const是对let的一个增强,它能阻止对一个变量再次赋值。
因为TypeScript是JavaScript的超集,所以它本身就支持let和const。
下面我们会详细说明这些新的声明方式以及为什么推荐使用它们来代替 var。
var
for (var i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i); // 输出 5 次 5 ❓
}, 100);
}
缺点:
- 那时候var 是唯一的变量声明方式
- 变量提升(hoisting) 让人迷惑
- 函数作用域 导致很多意外闭包问题
- i 在循环结束后还能访问,但值已经变了
后来ES6带来了let 和 const
for (let i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i); // 输出 0,1,2,3,4 ✅
}, 100);
}
let的好处:
- 块级作用域({} 内有效)
- 不会变量提升到全局
- 每次循环生成新的绑定(配合闭包更友好)
const的好处:
- 声明常量,值不能重新赋值
- 提升代码可读性:这个值“不会变”
- 配合对象时,属性仍可变(除非用 Object.freeze)
// 优先使用 const
const API_BASE = 'https://api.example.com';
const users: User[] = [];
// 只在需要重新赋值时用 let
let currentUser: User | null = null;
for (let i = 0; i < users.length; i++) {
// i 是块级变量
}
┌──────────────────────┬─────────────────────┬─────────────────────┬─────────────────────┐
│ 特性 │ const │ let │ var │
├─────────────────────┼─────────────────────┼─────────────────────┼─────────────────────┤
│ 能否重新赋值? │ 不能 │ 能 │ 能 │
│ │ 一旦声明,值的引用 │ 可以多次赋值 │ 可以多次赋值 │
│ │ 不能再改变 │ │ │
├─────────────────────┼─────────────────────┼─────────────────────┼─────────────────────┤
│ 作用域 │ 块级作用域 │ 块级作用域 │ 函数作用域 │
│ │ { } 内有效 │ { } 内有效 │ function 内有效 │
│ │ if、for、{} 中限制 │ 同上 │ 可以跨块访问 │
├─────────────────────┼─────────────────────┼─────────────────────┼─────────────────────┤
│ 变量提升(Hoisting)│ 有提升 │ 有提升 │ 有提升 │
│ │ 但存在“暂时性死区” │ 存在“暂时性死区” │ 提升到函数顶部 │
│ │ 不能在声明前访问 │ 不能在声明前访问 │ 值为 undefined │
├─────────────────────┼─────────────────────┼─────────────────────┼─────────────────────┤
│ 重复声明 │ 不允许 │ 不允许 │ 允许 │
│ │ const x = 1; │ let x = 1; │ var x = 1; │
│ │ const x = 2; // 报错 │ let x = 2; // 报错 │ var x = 2; // OK │
├─────────────────────┼─────────────────────┼─────────────────────┼─────────────────────┤
│ 全局对象属性 │ 不会成为 window 属性│ 不会成为 window 属性│ 会成为 window 属性 │
│ (浏览器中) │ │ │ var x = 1 → window.x │
├─────────────────────┼─────────────────────┼─────────────────────┼─────────────────────┤
│ 推荐程度 │ 优先使用 │ 需要修改时使用 │ 不推荐使用 │
│ │ “不变优先”原则 │ “可变时才用” │ 已被取代 │
├─────────────────────┼─────────────────────┼─────────────────────┼─────────────────────┤
│ 典型用法 │ 常量、配置、对象/数组│ 循环变量、状态变化 │ 老代码、全局变量 │
│ │ 的引用不变 │ (i++, loading = true)│ │
└─────────────────────┴─────────────────────┴─────────────────────┴─────────────────────┘