Javascript中有三种声明变量的方式:var, let, const
虽然它们都能用来声明变量,但在作用域、变量提升、重复声明等方面有着重要区别
var name = "Kayn"; // 老式写法,有作用域问题let age = 17; // 现代写法,块级作用域const PI = 3.14159; // 常量,声明后不能修改var 是 JavaScript 最早的变量声明方式,但它有一些问题:
var 声明的变量只有函数作用域,没有块级作用域
function example() { if (true) { var x = 1; } console.log(x); // 输出 1,x 在整个函数内都可访问}
// 对比块级作用域for (var i = 0; i < 3; i++) { // i 在这里声明}console.log(i); // 输出 3,i 泄漏到了全局作用域var 声明会被”提升”到函数或全局作用域的顶部
console.log(x); // undefined(而不是报错)var x = 5;
// 实际上相当于:var x; // 声明被提升到顶部console.log(x); // undefinedx = 5; // 赋值仍在原位置var name = "Kayn";var name = "Alice"; // 不会报错,但可能导致混淆console.log(name); // "Alice"let 是 ES6 引入的现代变量声明方式,解决了 var 的问题:
function example() { if (true) { let x = 1; } console.log(x); // ReferenceError: x is not defined}
// for 循环中的应用for (let i = 0; i < 3; i++) { // i 只在这个块内有效}console.log(i); // ReferenceError: i is not definedlet 不会被提升到可用状态,在声明前访问会报错
console.log(x); // ReferenceError: Cannot access 'x' before initializationlet x = 5;let name = "Kayn";let name = "Alice"; // SyntaxError: Identifier 'name' has already been declaredconst 用于声明常量,具有 let 的所有特性,但有额外限制:
const PI = 3.14159; // 正确const x; // SyntaxError: Missing initializer in const declarationconst name = "Kayn";name = "Alice"; // TypeError: Assignment to constant variableconst 只是不允许重新赋值,但对象和数组的内容仍然可以修改
const person = { name: "Kayn" };person.name = "Alice"; // 允许,修改对象属性person.age = 17; // 允许,添加新属性
const numbers = [1, 2, 3];numbers.push(4); // 允许,修改数组内容// numbers = [5, 6, 7]; // 不允许,重新赋值会报错const:如果值不需要重新赋值let:如果值需要重新赋值var:除非在维护老代码// ✅ 推荐写法const baseUrl = "https://api.example.com"; // 不会改变的值let currentUser = null; // 可能会重新赋值const users = []; // 数组本身不会重新赋值,但内容会变化
// ❌ 不推荐写法var apiKey = "secret"; // 作用域问题var counter = 0; // 可能导致意外的变量提升| 声明方式 | 作用域 | 变量提升 | 重复声明 | 重新赋值 |
|---|---|---|---|---|
var | 函数作用域 | 是 | 允许 | 允许 |
let | 块级作用域 | 暂时性死区 | 不允许 | 允许 |
const | 块级作用域 | 暂时性死区 | 不允许 | 不允许 |
// 使用 var 的问题for (var i = 0; i < 3; i++) { setTimeout(() => { console.log(i); // 输出三个 3 }, 100);}
// 使用 let 的解决方案for (let i = 0; i < 3; i++) { setTimeout(() => { console.log(i); // 输出 0, 1, 2 }, 100);}现代 JavaScript 开发中,正确使用 let 和 const 可以避免很多由作用域引起的 bug,让代码更加安全和可预测。