JavaScript中的let和const详解
编程小白也能轻松理解的变量声明指南
为什么需要let和const?
在ES6(JavaScript的2015年版本)之前,我们只能使用var
来声明变量。但var
有一些”奇怪”的行为:
1. 没有块级作用域:在{}
代码块中声明的变量,在代码块外部也能访问
2. 变量提升:变量可以在声明之前使用(值为undefined)
3. 可以重复声明:同一个变量可以多次声明
4. 全局变量问题:容易意外创建全局变量
为了解决这些问题,ES6引入了let
和const
,让变量声明更加合理和可控。
let关键字详解
1. 块级作用域
let
声明的变量只在它所在的代码块({}
之间)内有效。
// 使用var – 没有块级作用域
if (true) {
// var声明的变量在代码块外部也能访问
var message = “Hello”;
}
console.log(message); // 输出 “Hello”
// 使用let – 有块级作用域
if (true) {
// let声明的变量只在代码块内部有效
let greeting = “Hi”;
}
console.log(greeting); // 报错:greeting is not defined
if (true) {
// var声明的变量在代码块外部也能访问
var message = “Hello”;
}
console.log(message); // 输出 “Hello”
// 使用let – 有块级作用域
if (true) {
// let声明的变量只在代码块内部有效
let greeting = “Hi”;
}
console.log(greeting); // 报错:greeting is not defined
2. 不能重复声明
在同一个作用域内,let
不允许重复声明同一个变量。
// 使用var可以重复声明
var age = 20;
var age = 30; // 不会报错
// 使用let重复声明会报错
let score = 95;
let score = 100; // 报错:Identifier ‘score’ has already been declared
var age = 20;
var age = 30; // 不会报错
// 使用let重复声明会报错
let score = 95;
let score = 100; // 报错:Identifier ‘score’ has already been declared
3. 暂时性死区(TDZ)
在变量声明之前,该变量是不可用的。这个区域叫做”暂时性死区”。
// 使用var – 变量提升
console.log(name); // 输出 undefined(不会报错)
var name = “Alice”;
// 使用let – 暂时性死区
console.log(city); // 报错:Cannot access ‘city’ before initialization
let city = “Beijing”;
console.log(name); // 输出 undefined(不会报错)
var name = “Alice”;
// 使用let – 暂时性死区
console.log(city); // 报错:Cannot access ‘city’ before initialization
let city = “Beijing”;
4. 全局作用域中的let
在全局作用域中,let
声明的变量不会成为window对象的属性。
var globalVar = 10;
let globalLet = 20;
console.log(window.globalVar); // 10
console.log(window.globalLet); // undefined
let globalLet = 20;
console.log(window.globalVar); // 10
console.log(window.globalLet); // undefined
const关键字详解
1. 常量声明
const
用于声明常量,声明后其值不能被重新赋值。
const PI = 3.14159;
PI = 3.14; // 报错:Assignment to constant variable
PI = 3.14; // 报错:Assignment to constant variable
2. 必须初始化
const
声明时必须立即初始化(赋值)。
const MAX_SIZE; // 报错:Missing initializer in const declaration
MAX_SIZE = 100;
MAX_SIZE = 100;
3. 块级作用域
和let
一样,const
也具有块级作用域。
if (true) {
const COLOR = “red”;
}
console.log(COLOR); // 报错:COLOR is not defined
const COLOR = “red”;
}
console.log(COLOR); // 报错:COLOR is not defined
4. 常量与对象
当const
声明一个对象时,不能重新赋值,但可以修改对象的属性。
const person = {
name: “Bob”,
age: 30
};
// 可以修改对象的属性
person.age = 31; // 允许
// 但不能重新赋值整个对象
person = { name: “Alice” }; // 报错:Assignment to constant variable
name: “Bob”,
age: 30
};
// 可以修改对象的属性
person.age = 31; // 允许
// 但不能重新赋值整个对象
person = { name: “Alice” }; // 报错:Assignment to constant variable
小贴士: 使用const
声明对象时,虽然对象本身不能被重新赋值,但对象的属性是可以修改的。如果想完全冻结对象,使其属性也不能修改,可以使用Object.freeze()
。
let和const对比
特性 | let | const | var |
---|---|---|---|
作用域 | 块级作用域 | 块级作用域 | 函数作用域 |
变量提升 | 有暂时性死区 | 有暂时性死区 | 提升到函数顶部 |
重复声明 | 不允许 | 不允许 | 允许 |
重新赋值 | 允许 | 不允许 | 允许 |
全局作用域行为 | 不成为window属性 | 不成为window属性 | 成为window属性 |
必须初始化 | 不必 | 必须 | 不必 |
最佳实践建议:
1. 默认使用const
– 当你需要一个不会重新赋值的变量时
2. 需要重新赋值时使用let
– 当你需要一个会改变的变量时
3. 避免使用var
– 除非在特殊情况下(如需要函数作用域)
重要提示: 虽然const
声明的变量不能重新赋值,但如果它指向一个对象或数组,对象或数组的内容是可以修改的。这叫做”浅层不可变性”。
总结:如何选择let或const?
简单来说,记住这个规则:
// 1. 默认使用const
const name = “张三”; // 不会改变的值
const birthYear = 1990; // 不会改变的值
const colors = [“red”, “green”, “blue”]; // 数组引用不变
// 2. 需要重新赋值时使用let
let age = 30; // 年龄会变化
let score = 0; // 分数会变化
let currentUser = null; // 当前用户会变化
// 3. 避免使用var
// var oldVariable = “不要这样声明”;
const name = “张三”; // 不会改变的值
const birthYear = 1990; // 不会改变的值
const colors = [“red”, “green”, “blue”]; // 数组引用不变
// 2. 需要重新赋值时使用let
let age = 30; // 年龄会变化
let score = 0; // 分数会变化
let currentUser = null; // 当前用户会变化
// 3. 避免使用var
// var oldVariable = “不要这样声明”;
使用这个原则,可以让你的代码更安全、更易读、更易维护!