JavaScript 变量定义:var、let、const
简介
JavaScript 中变量声明经历了从 ES5 的 var 到 ES6(ES2015)引入的 let 和 const 的演进。理解三者的区别对于编写健壮的 JS 代码至关重要。
var
var 是 ES5 及之前唯一的变量声明方式。
var name = 'Alice';
var age = 25;
特点:
- 函数作用域:变量在声明它的整个函数内可见,而非块级作用域。
if (true) {
var x = 10;
}
console.log(x); // 10 — 在块外仍然可访问
- 变量提升(Hoisting):声明会被提升到函数或全局作用域的顶部,值为
undefined。
console.log(a); // undefined(不会报错)
var a = 5;
// 等价于:
// var a;
// console.log(a);
// a = 5;
- 可重复声明:同一作用域内可以重复声明同名变量,不会报错。
var count = 1;
var count = 2; // 不会报错,count 被重新声明
console.log(count); // 2
- 可重新赋值:变量的值可以随时改变。
let
let 是 ES6 引入的块级作用域变量声明方式。
let name = 'Bob';
let score = 100;
特点:
- 块级作用域:变量仅在声明它的代码块
{}内可见。
if (true) {
let y = 20;
console.log(y); // 20
}
console.log(y); // ReferenceError: y is not defined
- 暂时性死区(Temporal Dead Zone):在声明之前访问变量会报错,不存在变量提升。
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 10;
- 不可重复声明:同一作用域内不能重复声明同名变量。
let count = 1;
let count = 2; // SyntaxError: Identifier 'count' has already been declared
- 可重新赋值:变量的值可以改变。
let total = 50;
total = 100;
console.log(total); // 100
const
const 也是 ES6 引入的,用于声明常量。
const PI = 3.14159;
const API_URL = 'https://api.example.com';
特点:
- 块级作用域:与
let相同,仅在块内可见。
if (true) {
const z = 30;
console.log(z); // 30
}
console.log(z); // ReferenceError: z is not defined
- 必须初始化:声明时必须同时赋值。
const MAX_SIZE; // SyntaxError: Missing initializer in const declaration
- 不可重新赋值:变量绑定不可变,不能指向其他值。
const city = 'Beijing';
city = 'Shanghai'; // TypeError: Assignment to constant variable
- 对象/数组内容可修改:
const只保证变量指向的引用不变,对象属性或数组元素可以修改。
const person = { name: 'Alice' };
person.name = 'Bob'; // 允许
person.age = 30; // 允许
// person = {}; // 报错
const arr = [1, 2, 3];
arr.push(4); // 允许
// arr = []; // 报错
- 不可重复声明:与
let相同。
三者对比
| 特性 | var | let | const |
|---|---|---|---|
| 作用域 | 函数作用域 | 块级作用域 | 块级作用域 |
| 变量提升 | 有(值为 undefined) | 无(暂时性死区) | 无(暂时性死区) |
| 重复声明 | 允许 | 不允许 | 不允许 |
| 重新赋值 | 允许 | 允许 | 不允许 |
| 必须初始化 | 否 | 否 | 是 |
| 推荐程度 | 不推荐 | 推荐 | 优先使用 |
最佳实践
-
优先使用
const:如果变量不需要重新赋值,用const。这能明确表达意图,避免意外修改。 -
需要重新赋值时用
let:当变量值会变化时,使用let。 -
避免使用
var:在现代 JavaScript 开发中,var的作用域规则和提升行为容易导致 bug,应尽量避免使用。
// 推荐写法
const API_KEY = 'abc123';
const users = [];
let counter = 0;
counter++;
// 不推荐
var oldWay = 'avoid this';