Spread vs Rest 操作符在 JavaScript 中:像专业人士一样展开或收集
Source: Dev.to
介绍
想象一下,你在 JavaScript 中处理数组和对象,需要复制、合并或切片它们,而不费吹灰之力。
这时 展开运算符 (...) 和 剩余运算符 (...) 登场——两个看起来相同但职责不同的语法超级英雄。它们是现代 JavaScript 中编写简洁、可读代码的游戏规则改变者,尤其在 React 应用和 Node.js 后端中。
- 展开 将 值展开为单个元素。
- 剩余 将 值收集到一个数组或对象中。
让我们通过示例深入了解,看看它们在真实场景中的精彩表现。
扩展运算符的作用:展开值
扩展运算符(...)接受一个可迭代对象——比如数组或对象——并 展开(扩展)其元素为单独的项。它就像把盒子打开一样:所有内容都倾泻出来,便于使用。
const fruits = ['apple', 'banana'];
const moreFruits = ['orange', ...fruits, 'grape'];
// Result: ['orange', 'apple', 'banana', 'grape']
const user = { name: 'Ritam', city: 'Kolkata' };
const updatedUser = { ...user, age: 20, hobby: 'coding' };
// Result: { name: 'Ritam', city: 'Kolkata', age: 20, hobby: 'coding' }
扩展运算符会创建 浅拷贝 并进行合并——非常适合在状态管理中进行不可变更新。

Rest 运算符的作用:收集值
剩余运算符(...)的作用正好相反:它 收集 元素到一个数组(或对象)中。它可用于函数参数和解构赋值,充当“真空”,把剩余的值全部抓取进来。
function sum(...numbers) {
return numbers.reduce((acc, num) => acc + num, 0);
}
sum(1, 2, 3, 4); // Result: 10 (numbers = [1, 2, 3, 4])
const [first, ...rest] = ['apple', 'banana', 'orange']; // Array destructuring
console.log(first); // 'apple'
console.log(rest); // ['banana', 'orange']
它先抓取第一个元素,然后把其余的收集起来。

关键区别:展开运算符 与 剩余参数
| 方面 | 展开运算符 (...) | 剩余参数 (...) |
|---|---|---|
| 方向 | 展开(解包) | 收集(打包) |
| 上下文 | 任何位置(数组、对象、函数调用) | 函数参数或解构 |
| 使用场景 | 复制、合并、传递参数 | 可变参数、解构剩余部分 |
| 示例 | [...arr] 克隆数组 | function(...args) 收集参数 |
展开运算符用于向外展开值;剩余参数用于向内收集值。混淆它们会导致代码出错——展开运算符不能用于参数列表。
实际用例:真实世界的成功
克隆数组/对象(展开)
避免在 React 状态中产生变异。
const state = { users: [] };
const newState = { ...state, users: [...state.users, newUser] };
函数参数(展开)
动态传递数组。
const coords = [10, 20];
console.log(Math.max(...coords)); // 20
API 数据合并(展开)
将默认值与用户输入合并。
const defaults = { method: 'GET' };
const config = { ...defaults, url: '/api/users' };
fetch(config.url, config);
Node.js 工具中的可变参数(剩余参数)
构建灵活的辅助函数。
function log(...messages) {
console.log(new Date(), ...messages);
}
log('User login:', userId, timestamp);
解构 Props(剩余参数) – React
function Button({ children, ...props }) {
return {children};
}
这些模式随处可见——从 Vercel 的全栈部署到面试编程环节。
总结:掌握两者以编写更简洁的 JS
Spread 和 Rest 运算符将笨拙的数组/对象操作转化为优雅的一行代码,帮助你在全栈开发中减少头疼。记住:
- Spread 展开 用于复制/合并。
- Rest 收集 用于灵活的参数。
通过小例子进行练习,它们会在你的项目中变成第二天性。下次重构 Node.js 路由或 React 组件时,使用 ...——你的未来的自己会感谢你的。