javascript
ES6 解构赋值与扩展运算符
By AI-Writer 12 min read
ES6 引入的解构赋值(Destructuring Assignment)和扩展运算符(Spread Operator)是 JavaScript 中最常用、最能提升代码可读性的语法特性。它们让从对象或数组中提取数据、合并集合变得异常简洁。
数组解构
数组解构允许你按照位置从数组中提取元素。
基本语法
javascript
const colors = ['red', 'green', 'blue'];
// 传统方式
const r = colors[0];
const g = colors[1];
const b = colors[2];
// 解构赋值
const [r, g, b] = colors;
console.log(r, g, b); // 'red' 'green' 'blue'跳过元素与默认值
javascript
const numbers = [1, 2, 3, 4, 5];
// 跳过前两个元素
const [, , third] = numbers;
console.log(third); // 3
// 提供默认值(当解构值为 undefined 时生效)
const [a = 10, b = 20, c = 30] = [1, undefined];
console.log(a, b, c); // 1 20 30嵌套数组解构
javascript
const matrix = [[1, 2], [3, 4]];
const [[a, b], [c, d]] = matrix;
console.log(a, b, c, d); // 1 2 3 4对象解构
对象解构按照属性名匹配提取值,而非位置。
基本语法
javascript
const user = { name: 'Alice', age: 28, city: 'Beijing' };
// 属性名必须与对象键匹配
const { name, age } = user;
console.log(name, age); // 'Alice' 28
// 解构为不同变量名
const { name: userName, age: userAge } = user;
console.log(userName, userAge); // 'Alice' 28默认值与嵌套解构
javascript
const config = {
host: 'localhost',
port: 3000,
db: { type: 'mysql', pool: { min: 2, max: 10 } }
};
// 默认值 + 嵌套解构
const {
host,
port,
timeout = 5000, // 默认值
db: {
type,
pool: { min, max } // 深层解构
}
} = config;
console.log(timeout); // 5000(原对象无此属性)
console.log(min, max); // 2 10函数参数中的解构
解构在函数参数中尤为实用,避免了频繁访问 options.xxx:
javascript
// 传统写法
function createUser(options) {
const name = options.name;
const role = options.role || 'user';
// ...
}
// 解构写法
function createUser({ name, role = 'user', age = 18 }) {
console.log(`创建用户: ${name}, 角色: ${role}, 年龄: ${age}`);
}
createUser({ name: 'Bob' });
// 创建用户: Bob, 角色: user, 年龄: 18Rest 参数
Rest 参数(...rest)用于收集剩余的元素,只能出现在解构模式的末尾。
数组 Rest
javascript
const [first, ...rest] = [1, 2, 3, 4, 5];
console.log(first); // 1
console.log(rest); // [2, 3, 4, 5]对象 Rest(ES2018)
javascript
const person = { id: 1, name: 'Alice', age: 28, city: 'Beijing' };
// 提取 id,其余属性归入 info
const { id, ...info } = person;
console.log(id); // 1
console.log(info); // { name: 'Alice', age: 28, city: 'Beijing' }Rest 参数是浅拷贝——它复制的是引用,而非深层克隆。
展开运算符
展开运算符(...)是 rest 的逆操作:将可迭代对象或对象字面量展开为独立元素。
数组展开
javascript
const arr1 = [1, 2];
const arr2 = [3, 4];
// 合并数组
const merged = [...arr1, ...arr2, 5];
console.log(merged); // [1, 2, 3, 4, 5]
// 复制数组(浅拷贝)
const copy = [...arr1];
copy.push(99);
console.log(arr1); // [1, 2] —— 原数组不受影响
// 将类数组或可迭代对象转为数组
const str = 'hello';
const chars = [...str];
console.log(chars); // ['h', 'e', 'l', 'l', 'o']对象展开(ES2018)
javascript
const defaults = { theme: 'dark', lang: 'en' };
const overrides = { lang: 'zh', fontSize: 16 };
// 合并对象,后面的属性覆盖前面的
const settings = { ...defaults, ...overrides };
console.log(settings);
// { theme: 'dark', lang: 'zh', fontSize: 16 }
// 对象浅拷贝
const clone = { ...settings };对象展开是浅拷贝:嵌套对象仍然共享引用。
在函数调用中的应用
展开运算符可以将数组元素作为独立参数传递:
javascript
const nums = [3, 1, 4, 1, 5];
// 传统:Math.max.apply(null, nums)
const max = Math.max(...nums);
console.log(max); // 5
// 与 new 配合使用(ES2015+)
const dateParts = [2026, 3, 26];
const d = new Date(...dateParts);
console.log(d); // 2026-04-26(注意:月份从 0 开始)解构与展开的经典组合模式
1. 状态更新(不可变更新)
javascript
const state = { user: { name: 'Alice' }, count: 0 };
// React/Redux 风格的状态更新
const newState = {
...state,
user: { ...state.user, name: 'Bob' },
count: state.count + 1
};2. 从数组中提取头和尾
javascript
const queue = ['a', 'b', 'c', 'd'];
const [head, ...tail] = queue;
console.log(head); // 'a'
console.log(tail); // ['b', 'c', 'd']3. 多重返回值模拟
javascript
function parseUrl(url) {
const match = url.match(/^(https?):\/\/([^\/]+)(\/.*)?$/);
if (!match) return null;
const [, protocol, host, path = '/'] = match;
return { protocol, host, path };
}
const { protocol, host } = parseUrl('https://example.com/api');常见陷阱
解构 null 与 undefined
对 null 或 undefined 进行解构会抛出 TypeError,空对象解构则安全无影响:
javascript
const {} = {}; // OK,只是没有绑定任何变量
const {} = null; // TypeError!
const {} = undefined; // TypeError!默认值仅在 undefined 时生效
javascript
const { a = 1 } = { a: null };
console.log(a); // null,不是 1
const { b = 1 } = { b: undefined };
console.log(b); // 1展开运算符是浅拷贝
javascript
const obj = { nested: { value: 1 } };
const clone = { ...obj };
clone.nested.value = 2;
console.log(obj.nested.value); // 2 —— 嵌套对象被共享!小结
| 特性 | 用途 | 示例 |
|---|---|---|
| 数组解构 | 按位置提取 | const [a, b] = arr |
| 对象解构 | 按属性名提取 | const { x } = obj |
| 重命名 | 解构到不同变量 | const { x: y } = obj |
| 默认值 | 处理缺失值 | const { x = 1 } = obj |
| Rest | 收集剩余 | const [a, ...rest] = arr |
| 展开 | 分散元素 | [...arr1, ...arr2] |
解构赋值和展开运算符是现代 JavaScript 代码的基石,掌握它们能让你写出更声明式、更简洁的代码。
#javascript
#es6
#解构赋值
#扩展运算符
评论
A
Written by
AI-Writer
Related Articles
javascript
#10 Proxy、Reflect 与 Symbol
深入探索 JavaScript 元编程三大利器——Proxy 拦截器、Reflect API 与 Symbol 类型,掌握可劫持的语言行为与自定义迭代协议。
Read More javascript
#1 JavaScript 变量与数据类型
深入理解 var、let、const 的作用域规则,以及 JavaScript 原始类型与引用类型的本质区别与类型判断方法
Read More javascript
#11 数组内置方法综合运用
深入掌握 forEach、map、filter、reduce、find、sort 等数组方法的组合技巧,避开常见性能陷阱,写出更高效的函数式代码。
Read More