在JavaScript中,const
和let
是ES6引入的用于声明变量的关键字,它们在作用域、重新赋值、提升等方面有一些显著的区别
1. 作用域
let
和 const
: 均为块级作用域(block scope)。这意味着它们在代码块 {}
内声明后,只在该代码块内有效。块级作用域有助于避免变量提升带来的问题。
if (true) {
let x = 10;
const y = 20;
}
console.log(x); // ReferenceError: x is not defined
console.log(y); // ReferenceError: y is not defined
与之对比,var
是函数级作用域,在函数内声明的变量在整个函数中都有效,甚至在声明之前也可以访问(但未赋值时为undefined
)。
2. 重新赋值
let
: 可以重新赋值。
let x = 10;
x = 20; // 合法
console.log(x); // 20
const
: 声明时必须赋值,且不能重新赋值。如果尝试重新赋值,会抛出错误。
const y = 30;
y = 40; // TypeError: Assignment to constant variable.
需要注意的是,const
声明的对象或数组,其内部内容是可以修改的,但引用本身不可变。
const obj = { name: "John" };
obj.name = "Doe"; // 合法
console.log(obj.name); // Doe
obj = {}; // TypeError: Assignment to constant variable.
3. 变量提升
let
和 const
: 具有“暂时性死区”,即在声明之前访问会抛出ReferenceError
,它们不会像var
那样被提升到作用域的顶部。
console.log(a); // ReferenceError: Cannot access 'a' before initialization
let a = 5;
console.log(b); // ReferenceError: Cannot access 'b' before initialization
const b = 10;
var
: 变量提升到作用域顶部,在声明之前可以访问,值为undefined
。
console.log(c); // undefined
var c = 10;
4. 全局对象属性
let
和 const
: 在全局作用域中声明的变量不会成为全局对象(如window
)的属性。
5.重复声明
let
和 const
: 不允许在同一作用域内重复声明同一个变量。
let a = 5;
let a = 10; // SyntaxError: Identifier 'a' has already been declared
const b = 20;
const b = 30; // SyntaxError: Identifier 'b' has already been declared
var
: 允许在同一作用域内重复声明同一个变量。
var c = 40;
var c = 50; // 合法
console.log(c); // 50
所以
let
用于需要在后续代码中重新赋值的变量,并且只在块级作用域内有效。const
用于声明常量,值一旦赋值就不能被重新赋值,适合不变的数据。它也具有块级作用域。var
是旧的变量声明方式,具有函数级作用域和变量提升特性,现已较少使用。