let、const 与 var的区别
var
、let
和 const
是 JavaScript 中用于声明变量的关键字,它们在作用域、提升(hoisting)和可变性等方面有显著区别。以下是它们的详细对比:
1. 作用域
-
var
:- 函数作用域(function-scoped)。
- 在函数内部声明的变量只能在函数内部访问。
- 如果在函数外部声明,则为全局作用域。
- 示例:
function test() { var x = 10; if (true) { var y = 20; } console.log(x); // 10 console.log(y); // 20(y 在 if 块外仍然可访问) } test();
-
let
和const
:- 块级作用域(block-scoped)。
- 在
{}
块内声明的变量只能在块内访问。 - 示例:
function test() { let x = 10; if (true) { let y = 20; console.log(x); // 10 } console.log(y); // 报错:y 未定义 } test();
2. 变量提升(Hoisting)
-
var
:- 变量声明会被提升到作用域的顶部,但赋值不会。
- 示例:
console.log(x); // undefined(声明被提升,但未赋值) var x = 10;
-
let
和const
:- 声明也会被提升,但在赋值之前会处于“暂时性死区”(Temporal Dead Zone, TDZ),访问会报错。
- 示例:
console.log(x); // 报错:Cannot access 'x' before initialization let x = 10;
3. 可变性
-
var
和let
:- 声明的变量可以被重新赋值。
- 示例:
var x = 10; x = 20; // 合法 let y = 10; y = 20; // 合法
-
const
:- 声明的变量不能被重新赋值(常量)。
- 注意:如果
const
声明的是对象或数组,其属性或元素可以被修改。 - 示例:
const x = 10; x = 20; // 报错:Assignment to constant variable const obj = { name: "Alice" }; obj.name = "Bob"; // 合法 obj = {}; // 报错:Assignment to constant variable
4. 重复声明
-
var
:- 允许在同一作用域内重复声明。
- 示例:
var x = 10; var x = 20; // 合法
-
let
和const
:- 不允许在同一作用域内重复声明。
- 示例:
let x = 10; let x = 20; // 报错:Identifier 'x' has already been declared const y = 10; const y = 20; // 报错:Identifier 'y' has already been declared
5. 全局作用域下的行为
-
var
:- 在全局作用域下声明的变量会成为全局对象(如
window
)的属性。 - 示例:
var x = 10; console.log(window.x); // 10(在浏览器环境中)
- 在全局作用域下声明的变量会成为全局对象(如
-
let
和const
:- 在全局作用域下声明的变量不会成为全局对象的属性。
- 示例:
let x = 10; console.log(window.x); // undefined(在浏览器环境中)
总结对比
特性 | var | let | const |
---|---|---|---|
作用域 | 函数作用域 | 块级作用域 | 块级作用域 |
提升 | 声明提升,赋值不提升 | 声明提升,但有暂时性死区 | 声明提升,但有暂时性死区 |
可变性 | 可重新赋值 | 可重新赋值 | 不可重新赋值 |
重复声明 | 允许 | 不允许 | 不允许 |
全局对象属性 | 是 | 否 | 否 |
使用建议
- 优先使用
const
:- 如果变量的值不会改变,使用
const
可以避免意外修改。
- 如果变量的值不会改变,使用
- 需要重新赋值时使用
let
:- 如果变量的值需要改变,使用
let
。
- 如果变量的值需要改变,使用
- 避免使用
var
:var
的作用域和提升行为容易导致 bug,现代 JavaScript 开发中应尽量避免使用。
通过合理使用 let
和 const
,可以写出更安全、更易维护的代码。