解构赋值(Destructuring)
概述
解构赋值是 ES6 引入的语法,允许从数组或对象中提取值,按照对应位置对变量赋值。
数组解构
基本用法
// 传统方式
const arr = [1, 2, 3];
const a = arr[0];
const b = arr[1];
const c = arr[2];
// 解构赋值
const [x, y, z] = [1, 2, 3];
console.log(x, y, z); // 1, 2, 3
跳过元素
const [first, , third] = [1, 2, 3];
console.log(first, third); // 1, 3
// 剩余元素
const [head, ...tail] = [1, 2, 3, 4, 5];
console.log(head); // 1
console.log(tail); // [2, 3, 4, 5]
默认值
const [a = 1, b = 2] = [10];
console.log(a, b); // 10, 2
// 只有解构值为 undefined 时才使用默认值
const [x = 5] = [null];
console.log(x); // null
交换变量
let a = 1;
let b = 2;
// 传统方式
let temp = a;
a = b;
b = temp;
// 解构赋值
[a, b] = [b, a];
console.log(a, b); // 2, 1
嵌套数组解构
const matrix = [[1, 2], [3, 4]];
const [[a, b], [c, d]] = matrix;
console.log(a, b, c, d); // 1, 2, 3, 4
const [first, [second, third]] = [1, [2, 3]];
console.log(first, second, third); // 1, 2, 3
对象解构
基本用法
// 传统方式
const person = { name: 'John', age: 25 };
const name = person.name;
const age = person.age;
// 解构赋值
const { name, age } = { name: 'John', age: 25 };
console.log(name, age); // John, 25
重命名变量
const person = { name: 'John', age: 25 };
// 属性名: 变量名
const { name: userName, age: userAge } = person;
console.log(userName, userAge); // John, 25
// 简写形式(属性名和变量名相同)
const { name, age } = person;
默认值
const person = { name: 'John' };
const { name, age = 30 } = person;
console.log(name, age); // John, 30
// 重命名 + 默认值
const { name: userName, age: userAge = 30 } = person;
console.log(userName, userAge); // John, 30
嵌套对象解构
const user = {
name: 'John',
address: {
city: 'New York',
country: 'USA'
}
};
const { name, address: { city, country } } = user;
console.log(name, city, country); // John, New York, USA
// 重命名嵌套属性
const { name, address: { city: userCity } } = user;
console.log(userCity); // New York
剩余属性
const person = { name: 'John', age: 25, city: 'New York', country: 'USA' };
const { name, age, ...others } = person;
console.log(name, age); // John, 25
console.log(others); // { city: 'New York', country: 'USA' }
函数参数解构
对象参数解构
// 传统方式
function createUser(options) {
const name = options.name || 'Anonymous';
const age = options.age || 0;
return { name, age };
}
// 解构赋值
function createUser({ name = 'Anonymous', age = 0 }) {
return { name, age };
}
// 箭头函数
const createUser = ({ name = 'Anonymous', age = 0 }) => ({ name, age });
const user = createUser({ name: 'John', age: 25 });
数组参数解构
function processCoords([x, y]) {
return { x, y };
}
const point = processCoords([10, 20]);
console.log(point); // { x: 10, y: 20 }
复杂参数解构
function displayUser({ name, address: { city } }) {
console.log(`${name} lives in ${city}`);
}
const user = {
name: 'John',
address: {
city: 'New York',
country: 'USA'
}
};
displayUser(user); // John lives in New York
实际应用示例
1. 从函数返回多个值
function getUserInfo() {
return {
name: 'John',
age: 25,
email: 'john@example.com'
};
}
const { name, age, email } = getUserInfo();
2. 处理 API 响应
async function fetchUser(id) {
const response = await fetch(`/api/users/${id}`);
const { data: { user, permissions } } = await response.json();
return { user, permissions };
}
3. 配置对象处理
function createServer({
port = 3000,
host = 'localhost',
ssl = false,
timeout = 5000
} = {}) {
console.log(`Server running on ${host}:${port}`);
// ...
}
createServer({ port: 8080, ssl: true });
4. React 组件 props
// React 组件
function UserCard({ name, age, avatar, onClick }) {
return (
<div onClick={onClick}>
<img src={avatar} alt={name} />
<h2>{name}</h2>
<p>Age: {age}</p>
</div>
);
}
注意事项
1. undefined 的处理
const { a } = { a: undefined };
console.log(a); // undefined
const { b = 1 } = { b: undefined };
console.log(b); // 1
const { c = 1 } = {};
console.log(c); // 1
2. 圆括号问题
// 错误:解构赋值不能在语句开头使用圆括号
// { a } = { a: 1 }; // SyntaxError
// 正确:使用圆括号包裹
({ a } = { a: 1 });
// 或者使用 let/const
let { a } = { a: 1 };
3. 已声明变量的解构
let x;
// { x } = { x: 1 }; // SyntaxError
({ x } = { x: 1 }); // 正确
let y;
[y] = [1]; // 正确(数组解构不需要圆括号)
最佳实践
- 保持简洁:避免过深的嵌套解构
- 使用默认值:提高代码健壮性
- 合理重命名:避免变量名冲突
- 注意性能:大量解构可能影响性能
// 好的做法
const { name, age = 0 } = user;
// 避免过深嵌套
const {
user: {
profile: {
settings: {
theme
}
}
}
} = data; // 过于复杂
// 更好的方式
const theme = data.user.profile.settings.theme;
参考
目录