JavaScript Let Const
在JavaScript的发展历程中,ES6(ECMAScript 2015)带来了许多重要更新,其中let
和const
关键字的引入是JavaScript变量声明方式的一次重大革新。这两个关键字为JavaScript提供了更加可预测和安全的变量声明方式,解决了使用var
声明变量时存在的各种问题。
传统变量声明:var的问题
在了解let
和const
之前,让我们先回顾一下使用var
声明变量时存在的主要问题:
1. 作用域问题
var
声明的变量具有函数作用域,而非块级作用域,这可能导致预期外的行为:
function exampleFunction() {
if (true) {
var x = 10;
}
console.log(x); // 输出: 10,即使x是在if块中声明的
}
exampleFunction();
2. 变量提升
var
声明的变量会被"提升"到其作用域的顶部:
console.log(y); // 输出: undefined,而非报错
var y = 5;
// 上面的代码等同于:
var y;
console.log(y);
y = 5;
3. 可重复声明
同一作用域内可以多次声明同一个变量:
var z = 10;
var z = 20; // 不会报错,z被重新赋值为20
现代变量声明:let和const
为了解决以上问题,ES6引入了let
和const
关键字,它们提供了更精确的变量声明控制。
let关键字
let
声明的变量具有块级作用域,并且不会被提升:
function testLet() {
if (true) {
let x = 10;
console.log(x); // 输出: 10
}
// console.log(x); // 报错: x is not defined
}
testLet();
let的主要特性
- 块级作用域:变量仅在声明它的代码块内可用。
- 没有变量提升:变量必须在声明前使用,否则会报错。
- 不允许重复声明:在同一作用域中不能多次声明同一个变量。
// 演示块级作用域
{
let blockScoped = "我只在这个块中可见";
console.log(blockScoped); // 输出: 我只在这个块中可见
}
// console.log(blockScoped); // 报错: blockScoped is not defined
// 演示无变量提升
// console.log(noHoisting); // 报错: Cannot access 'noHoisting' before initialization
let noHoisting = "我没有被提升";
// 演示不能重复声明
let noDuplicate = "第一次声明";
// let noDuplicate = "第二次声明"; // 报错: Identifier 'noDuplicate' has already been declared
const关键字
const
关键字用于声明常量,其值在初始化后不能更改:
const PI = 3.14159;
console.log(PI); // 输出: 3.14159
// PI = 3.14; // 报错: Assignment to constant variable
const的主要特性
- 块级作用域:与
let
相同,具有块级作用域。 - 必须初始化:声明时必须赋值,否则会报错。
- 不可重新赋值:一旦初始化,不能更改其值。
- 对于引用类型(对象、数组等),其内容仍可修改。
// 必须初始化
// const MUST_INITIALIZE; // 报错: Missing initializer in const declaration
// 引用类型内容可修改
const person = {
name: "张三",
age: 25
};
person.age = 26; // 有效 - 可以修改对象的属性
console.log(person); // 输出: {name: "张三", age: 26}
// person = {}; // 报错 - 不能重新赋值整个对象
提示
如果你需要一个完全不可变的对象,可以使用Object.freeze()
方法:
const frozenPerson = Object.freeze({
name: "李四",
age: 30
});
// frozenPerson.age = 31; // 严格模式下报错,非严格模式下静默失败
console.log(frozenPerson.age); // 输出: 30 (值未改变)
let vs const vs var:何时使用?
以下是选择变量声明方式的一些指导原则:
-
默认使用
const
:除非你知道变量值将来会改变,否则 首选使用const
。这有助于避免意外修改变量。 -
需要重新赋值时使用
let
:当变量的值需要更改时,如计数器、状态变量等,使用let
。 -
避免使用
var
:在现代JavaScript中,很少有理由继续使用var
。
// 推荐的做法
const API_URL = "https://api.example.com"; // 不会改变的值
let count = 0; // 会改变的值
function incrementCounter() {
count += 1;
return count;
}