Skip to content

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

最佳实践建议

  1. 默认使用const声明变量,这样可以防止意外的重新赋值
  2. 当需要重新赋值时,使用let
  3. 完全避免使用var,除非在特殊的兼容性场景
  4. 在循环中使用let来创建块级作用域的循环变量
javascript
// 推荐的写法
const MAX_USERS = 100;  // 常量使用const
let currentUsers = 0;   // 需要修改的变量使用let

for(let i = 0; i < MAX_USERS; i++) {
    // 循环变量使用let
    currentUsers++;
}