JavaScript 中有三种声明变量的方式:var、let 和 const。它们在作用域、重复声明、变量提升和可变性等方面存在关键差异。正确理解这些区别,能避免常见的运行时错误。
1. 作用域规则不同
作用域决定了变量在代码中的可见范围。
-
使用
var声明的变量具有函数作用域:只要在函数内部声明,整个函数内都可访问;若在全局作用域声明,则成为全局变量。function example() { if (true) { var x = 10; } console.log(x); // 输出 10,因为 var 是函数作用域 } -
使用
let或const声明的变量具有块级作用域:仅在{}包裹的代码块内有效(如if、for、while等语句内部)。function example() { if (true) { let y = 20; } console.log(y); // 报错:y is not defined }
记住:块级作用域让代码更安全,避免变量意外泄漏到外层。
2. 是否允许重复声明
在同一个作用域内:
-
var允许重复声明同一变量,不会报错,后一次声明会覆盖前一次(但不推荐)。var a = 1; var a = 2; // 合法,a 的值变为 2 -
let和const不允许重复声明,否则会抛出语法错误。let b = 1; let b = 2; // SyntaxError: Identifier 'b' has already been declared
注意:即使变量名相同,只要不在同一作用域,let/const 仍可声明。
3. 变量提升行为不同
变量提升指 JavaScript 引擎将变量声明“移动”到作用域顶部的行为。
-
var会被提升并初始化为undefined,因此可以在声明前访问(但值是undefined)。console.log(c); // 输出 undefined var c = 5; -
let和const虽然也会被提升,但不会被初始化。在声明前访问会进入“暂时性死区”(Temporal Dead Zone, TDZ),导致引用错误。console.log(d); // ReferenceError: Cannot access 'd' before initialization let d = 10;
结论:永远不要在声明前使用 let 或 const 变量。
4. 是否可以重新赋值
-
var和let声明的变量可以重新赋值。let e = 100; e = 200; // 合法 -
const声明的变量不能重新赋值,必须在声明时初始化。const f = 300; f = 400; // TypeError: Assignment to constant variable.
重要澄清:const 并非“完全不可变”。对于对象或数组,其属性或元素仍可修改,只是变量本身不能指向新值。
const obj = { name: "Alice" };
obj.name = "Bob"; // 合法,修改属性
obj = {}; // 非法,试图重新赋值
5. 全局对象绑定差异
在浏览器环境中,全局作用域下:
-
var声明的变量会自动成为window对象的属性。var g = "hello"; console.log(window.g); // "hello" -
let和const声明的变量不会挂载到window对象上。let h = "world"; console.log(window.h); // undefined
这使得 let/const 更干净,避免污染全局对象。
如何选择?最佳实践
遵循以下规则即可写出清晰可靠的代码:
- 优先使用
const:除非你确定变量需要重新赋值。 - 需要重新赋值时用
let:比如循环计数器、状态切换等。 - 避免使用
var:除非维护老旧代码,现代 JavaScript 开发应弃用var。
下面表格总结三者的核心区别:
| 特性 | var |
let |
const |
|---|---|---|---|
| 作用域 | 函数作用域 | 块级作用域 | 块级作用域 |
| 是否可重复声明 | 是 | 否 | 否 |
| 是否变量提升 | 是(初始化为 undefined) |
是(但有 TDZ) | 是(但有 TDZ) |
| 是否可重新赋值 | 是 | 是 | 否 |
是否挂载到 window |
是 | 否 | 否 |
| 声明时是否需初始化 | 否 | 否 | 是 |

暂无评论,快来抢沙发吧!