解构(Destructuring)是 ES6 引入的语法,可以从数组或对象中提取值,赋值给变量。
const arr = [1, 2, 3];
const [a, b, c] = arr;
console.log(a, b, c); // 1, 2, 3
const arr = [1, 2, 3, 4, 5];
const [first, , third, , fifth] = arr;
console.log(first, third, fifth); // 1, 3, 5
const arr = [1, 2];
const [a, b, c = 3] = arr;
console.log(a, b, c); // 1, 2, 3
const [x, y = 10] = [5];
console.log(x, y); // 5, 10
const arr = [1, 2, 3, 4, 5];
const [first, second, ...rest] = arr;
console.log(first); // 1
console.log(second); // 2
console.log(rest); // [3, 4, 5]
let a = 1;
let b = 2;
[a, b] = [b, a];
console.log(a, b); // 2, 1
const arr = [1, [2, 3], 4];
const [a, [b, c], d] = arr;
console.log(a, b, c, d); // 1, 2, 3, 4
const obj = { name: 'Alice', age: 25 };
const { name, age } = obj;
console.log(name, age); // 'Alice', 25
const obj = { name: 'Alice', age: 25 };
const { name: userName, age: userAge } = obj;
console.log(userName, userAge); // 'Alice', 25
const obj = { name: 'Alice' };
const { name, age = 18 } = obj;
console.log(name, age); // 'Alice', 18
const { city = 'Unknown' } = {};
console.log(city); // 'Unknown'
const obj = { name: 'Alice' };
const { name: userName, age: userAge = 18 } = obj;
console.log(userName, userAge); // 'Alice', 18
const obj = { name: 'Alice', age: 25, city: 'NYC' };
const { name, ...rest } = obj;
console.log(name); // 'Alice'
console.log(rest); // { age: 25, city: 'NYC' }
const obj = {
user: {
name: 'Alice',
age: 25
},
city: 'NYC'
};
const { user: { name, age }, city } = obj;
console.log(name, age, city); // 'Alice', 25, 'NYC'
// 重命名嵌套属性
const { user: { name: userName } } = obj;
console.log(userName); // 'Alice'
const key = 'name';
const obj = { name: 'Alice', age: 25 };
const { [key]: value } = obj;
console.log(value); // 'Alice'
function sum([a, b, c]) {
return a + b + c;
}
console.log(sum([1, 2, 3])); // 6
function greet({ name, age }) {
return `Hello, ${name}. You are ${age} years old.`;
}
console.log(greet({ name: 'Alice', age: 25 }));
// 'Hello, Alice. You are 25 years old.'
// 带默认值
function createUser({ name, age = 18, city = 'Unknown' }) {
return { name, age, city };
}
console.log(createUser({ name: 'Alice' }));
// { name: 'Alice', age: 18, city: 'Unknown' }
function config({ timeout = 1000, retries = 3 } = {}) {
return { timeout, retries };
}
console.log(config()); // { timeout: 1000, retries: 3 }
console.log(config({ timeout: 2000 })); // { timeout: 2000, retries: 3 }
function getCoordinates() {
return [10, 20];
}
const [x, y] = getCoordinates();
console.log(x, y); // 10, 20
function getUser() {
return { name: 'Alice', age: 25 };
}
const { name, age } = getUser();
console.log(name, age); // 'Alice', 25
const map = new Map([
['name', 'Alice'],
['age', 25]
]);
for (const [key, value] of map) {
console.log(key, value);
}
// name Alice
// age 25
async function fetchUser() {
const response = await fetch('/api/user');
const { data: { user, settings } } = await response.json();
return { user, settings };
}
// 使用
const { user, settings } = await fetchUser();
function createComponent({
name,
props = {},
children = [],
...otherOptions
}) {
return {
name,
props,
children,
...otherOptions
};
}
const component = createComponent({
name: 'Button',
onClick: () => {},
className: 'btn'
});
// 从模块中解构导入
import { useState, useEffect } from 'react';
import { map, filter, reduce } from 'lodash';
// 重命名导入
import { createUser as create } from './utils';
const arr = [1, 2, 3, 4, 5];
const [first, , , fourth] = arr;
console.log(first, fourth); // 1, 4
const obj = { a: 1, b: 2, c: 3 };
const { a, c } = obj;
console.log(a, c); // 1, 3
const user = getUser();
const { name, age } = user || {};
console.log(name, age); // 避免 user 为 null/undefined 时报错
let a, b;
({ a, b } = { a: 1, b: 2 });
console.log(a, b); // 1, 2
// 注意:必须用括号包裹,否则会被解析为代码块
const data = {
users: [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 }
],
meta: {
total: 2,
page: 1
}
};
// 解构嵌套数据
const {
users: [firstUser, secondUser],
meta: { total }
} = data;
console.log(firstUser); // { name: 'Alice', age: 25 }
console.log(total); // 2
// 更深层嵌套
const {
users: [{ name: firstName }]
} = data;
console.log(firstName); // 'Alice'
const [a] = [];
console.log(a); // undefined
const { b } = {};
console.log(b); // undefined
const { a } = null; // TypeError
const { a } = undefined; // TypeError
// 使用默认值避免
const { a = 1 } = null || {}; // 安全
const { a = 1 } = { a: null };
console.log(a); // null (不是 1)
const { b = 1 } = { b: undefined };
console.log(b); // 1
const obj = { nested: { value: 1 } };
const { nested } = obj;
nested.value = 2;
console.log(obj.nested.value); // 2 (被修改了)
// 这些会报错
const [a] = 'hello'; // 字符串会被转换为字符数组
const { a } = 'hello'; // TypeError: Cannot destructure property 'a' of 'hello'
const response = { status: 200, data: { users: [] } };
const { data: { users: userList } } = response;
console.log(userList); // []
function process({ input = '', options = {} } = {}) {
// 安全处理
}
let x = 1, y = 2;
[x, y] = [y, x];
// 之前
function createUser(options) {
const name = options.name;
const age = options.age || 18;
// ...
}
// 之后
function createUser({ name, age = 18 }) {
// ...
}