JavaScript let和const变量声明
在 JavaScript 中,变量声明有三种方式:var
、let
和 const
。在 ES6 中,let
和 const
作为新的声明方式被引入,相比于 var
,它们有更好的作用域控制和更严格的变量声明方式。
let 声明
let
用于声明一个块级作用域的变量,它可以被重新赋值。在同一个块级作用域内,不能重复声明同名变量。
let x = 1;
if (true) {
let x = 2; // 在块级作用域内重新声明 x 变量
console.log(x); // 输出 2
}
console.log(x); // 输出 1
const 声明
const
也用于声明块级作用域的变量,但它声明的变量是不可重新赋值的,也就是说,一旦声明后,就不能再改变其值。在同一个块级作用域内,不能重复声明同名变量。
const x = 1;
if (true) {
const x = 2; // 在块级作用域内重新声明 x 变量
console.log(x); // 输出 2
}
console.log(x); // 输出 1
如果尝试重新赋值 const
声明的变量,会抛出一个错误:
const x = 1;
x = 2; // TypeError: Assignment to constant variable.
但如果 const
声明的变量是一个对象或数组,那么可以改变对象或数组的属性值,只是不能改变整个对象或数组的引用。
const obj = {a: 1};
obj.a = 2; // 可以改变 obj 的属性值
console.log(obj); // 输出 {a: 2}
const arr = [1, 2, 3];
arr.push(4); // 可以改变 arr 的数组元素
console.log(arr); // 输出 [1, 2, 3, 4]
arr = [1, 2]; // TypeError: Assignment to constant variable.
let 和 const 的区别
let
和 const
的区别在于,let
声明的变量可以被重新赋值,而 const
声明的变量不可重新赋值。另外,let
和 const
都是块级作用域的变量,不能重复声明同名变量。
在实际应用中,我们需要根据具体情况来选择使用 let
或 const
。如果我们需要声明一个不可更改的常量,那么就应该使用 const
;如果我们需要声明一个可更改的变量,那么就应该使用 let
。
块级作用域
在 ES6 之前,JavaScript 中只有全局作用域和函数作用域,对于块级作用域的支持非常有限。在 ES6 中,let
和 const
声明的变量就是块级作用域的变量,它们只在声明的块级作用域内有效。
{
let x = 1;
const y = 2;
var z = 3;
}
console.log(x); // ReferenceError: x is not defined
console.log(y); // ReferenceError: y is not defined
console.log(z); // 输出 3
在上面的代码中,x
和 y
都是在块级作用域内声明的变量,只在这个块级作用域内有效,外部无法访问。而 z
是用 var
声明的变量,它没有块级作用域的概念,所以可以在块级作用域外访问。
暂时性死区
块级作用域内使用 let
和 const
声明的变量,会存在一个特殊的区域,称之为“暂时性死区(Temporal Dead Zone,TDZ)”。在这个区域内,变量虽然已经声明,但是在声明之前访问它都会抛出一个错误。
console.log(x); // ReferenceError: Cannot access 'x' before initialization
let x = 1;
在上面的代码中,虽然 x
已经声明了,但是在声明之前访问它,就会抛出一个错误。这是因为在 let
声明的变量被执行之前,它是不存在的,访问它就会导致 TDZ 的错误。
总结
let
和 const
是 ES6 中引入的新的变量声明方式,它们都是块级作用域的变量,可以有效地控制变量的作用域。let
声明的变量可以被重新赋值,而 const
声明的变量不可重新赋值。在块级作用域内,不能重复声明同名变量。使用 let
和 const
声明变量时,会存在暂时性死区的问题,访问未初始化的变量会抛出 TDZ 的错误。