var、let、const的深入理解
var 的特性与局限
在ES6之前,JavaScript中只有var这一种变量声明方式。让我们先来看看它的一些特性:
1. 变量提升现象
var声明的变量会被提升到当前作用域的顶部。这就像写作文时把重要词语提前列在开头一样:
javascript
console.log(name); // undefined
var name = "小明";
// 实际上JavaScript引擎会这样解析上面的代码:
var name;
console.log(name);
name = "小明";
2. 函数作用域
var只认识函数作用域,不认识块级作用域,这可能会导致一些意想不到的问题:
javascript
function test() {
if (true) {
var secret = "这是一个秘密";
}
console.log(secret); // "这是一个秘密",在if块外依然可以访问
}
test();
3. 可以重复声明
这个特性可能会导致代码维护的噩梦:
javascript
var count = 1;
var count = 2; // 完全合法,但可能会带来困扰
console.log(count); // 2
let 和 const 的改进
ES6引入的let和const解决了var的诸多问题,让我们来看看它们的特点:
1. 块级作用域
终于可以好好管理变量的作用范围了:
javascript
{
let blockScoped = "我只在这个块里有效";
const PI = 3.14159;
console.log(blockScoped); // 正常输出
console.log(PI); // 正常输出
}
console.log(blockScoped); // ReferenceError: blockScoped is not defined
console.log(PI); // ReferenceError: PI is not defined
2. 暂时性死区(TDZ)
变量必须先声明后使用,这让代码更加规范:
javascript
console.log(age); // ReferenceError: Cannot access 'age' before initialization
let age = 25;
3. 禁止重复声明
防止了意外的变量覆盖:
javascript
let user = "张三";
let user = "李四"; // SyntaxError: Identifier 'user' has already been declared
4. const的特殊之处
const声明的是常量,赋值后就不能改变:
javascript
const API_KEY = "abc123";
API_KEY = "xyz789"; // TypeError: Assignment to constant variable
// 但对于对象,可以修改其属性
const config = {
theme: "dark"
};
config.theme = "light"; // 这是允许的
config = {}; // TypeError: Assignment to constant variable
最佳实践建议
- 默认使用const声明变量,这样可以防止意外的重新赋值
- 当需要重新赋值时,使用let
- 完全避免使用var,除非在特殊的兼容性场景
- 在循环中使用let来创建块级作用域的循环变量
javascript
// 推荐的写法
const MAX_USERS = 100; // 常量使用const
let currentUsers = 0; // 需要修改的变量使用let
for(let i = 0; i < MAX_USERS; i++) {
// 循环变量使用let
currentUsers++;
}