当前位置: 首页 > news >正文

rest参数和spread扩展运算符

在 JavaScript 中,rest 参数spread 扩展运算符都使用...语法,但作用完全相反:rest 是“收集”元素spread 是“展开”元素。下面详细说明两者的用法和区别。

一、rest 参数(收集剩余元素)

rest 参数(剩余参数)用于收集多个元素,聚合成一个数组,主要用于两种场景:函数参数列表、数组/对象解构。

1. 函数参数中的 rest 参数

当函数需要接收不确定数量的参数时,用...变量名定义 rest 参数,它会将传入的多余参数收集为一个数组。

特点

  • rest 参数必须是函数的最后一个参数(否则报错)。
  • 收集的结果是真正的数组(可直接使用数组方法,如mapreduce)。

示例
求任意多个数字的和:

function sum(...nums) { // rest 参数 nums 收集所有传入的参数return nums.reduce((total, num) => total + num, 0);
}sum(1, 2); // 3(nums 是 [1,2])
sum(1, 2, 3, 4); // 10(nums 是 [1,2,3,4])

结合固定参数使用(rest 必须在最后):

function print(first, ...rest) { // first 接收第一个参数,rest 收集剩余参数console.log('第一个参数:', first);console.log('剩余参数:', rest);
}print('a', 'b', 'c', 'd'); 
// 第一个参数:a
// 剩余参数:['b', 'c', 'd']
2. 解构中的 rest 参数

在数组或对象解构时,用...变量名收集剩余未被解构的元素,聚合成数组或对象。

数组解构示例

const [a, b, ...rest] = [1, 2, 3, 4, 5];
console.log(a); // 1
console.log(b); // 2
console.log(rest); // [3,4,5](收集剩余元素)

对象解构示例

const { name, age, ...rest } = { name: '张三', age: 18, gender: '男', height: 180 };
console.log(name); // 张三
console.log(age); // 18
console.log(rest); // { gender: '男', height: 180 }(收集剩余属性)

二、spread 扩展运算符(展开元素)

spread 扩展运算符(展开运算符)用于将可迭代对象(如数组、字符串、Set)或对象“拆成”单个元素,主要用于数组字面量、对象字面量、函数调用等场景。

1. 数组中的 spread 运算符

用于合并数组复制数组(避免引用传递)、将类数组转为数组等。

示例 1:合并数组

const arr1 = [1, 2];
const arr2 = [3, 4];
const merged = [...arr1, ...arr2]; // 展开 arr1 和 arr2,再合并为新数组
console.log(merged); // [1,2,3,4]

示例 2:复制数组(深拷贝一层)

const original = [1, 2, 3];
const copy = [...original]; // 展开 original,生成新数组
copy.push(4); 
console.log(original); // [1,2,3](原数组不受影响)
console.log(copy); // [1,2,3,4]

示例 3:将字符串拆分为数组

const str = 'hello';
const arr = [...str]; // 展开字符串的每个字符
console.log(arr); // ['h','e','l','l','o']
2. 函数调用中的 spread 运算符

用于将数组元素拆分为函数的独立参数(解决函数需要多个参数,但只有数组的场景)。

示例
求数组中的最大值(Math.max()需要多个参数,而非数组):

const nums = [1, 3, 5, 2];
const max = Math.max(...nums); // 等价于 Math.max(1,3,5,2)
console.log(max); // 5
3. 对象中的 spread 运算符(ES2018 新增)

用于合并对象复制对象(浅拷贝),会覆盖重复的属性。

示例 1:合并对象

const obj1 = { name: '张三', age: 18 };
const obj2 = { gender: '男', age: 20 }; // 重复属性 age
const merged = { ...obj1, ...obj2 }; // 展开并合并,后展开的覆盖前的
console.log(merged); // { name: '张三', age: 20, gender: '男' }

示例 2:复制对象(浅拷贝)

const original = { a: 1, b: { c: 2 } };
const copy = { ...original }; 
copy.b.c = 3; // 修改拷贝对象的嵌套属性
console.log(original.b.c); // 3(原对象的嵌套属性受影响,因为是浅拷贝)

三、核心区别

核心区别
类型作用场景结果类型
rest 参数收集多个元素为数组/对象函数参数、数组/对象解构数组(函数/数组解构)、对象(对象解构)
spread 运算符展开元素为单个值数组字面量、对象字面量、函数调用拆分为独立元素
其他区别

rest 参数spread 扩展运算符虽然都使用...语法,但在使用位置、上下文要求、作用目标等语法层面有明确区别,核心差异如下:

1. 语法作用方向不同

  • rest 参数:是“收集”行为——将多个分散的元素“聚合”成一个数组或对象。
    例如:function fn(...rest) {} 中,...rest 会把传入的多个参数收集为数组 rest

  • spread 扩展运算符:是“展开”行为——将一个聚合对象(如数组、对象)“拆分”成单个元素。
    例如:[...arr] 中,...arr 会把数组 arr 的元素拆分成独立值,再组成新数组。

2. 使用位置与上下文限制不同

rest 参数的语法位置(严格限制):

只能用于两个场景,且必须作为“最后一个元素”出现:

  • 函数参数列表的末尾
    必须是函数的最后一个参数,后面不能有其他参数,否则报错。
    例:function fn(a, ...rest) {}(正确);function fn(...rest, a) {}(错误,语法报错)。

  • 数组/对象解构的末尾
    在解构时,...变量名 必须放在解构模式的最后,后面不能有其他解构项。
    例:const [a, ...rest] = [1,2,3](正确);const [...rest, a] = [1,2,3](错误,语法报错);
    例:const { x, ...rest } = {x:1, y:2, z:3}(正确);const {...rest, x} = {x:1, y:2}(错误)。

spread 扩展运算符的语法位置(灵活):

可用于多个场景,且可以在多个位置出现,无需作为最后一个元素:

  • 数组字面量中:可在任意位置展开,甚至多次使用。
    例:[1, ...arr, 3, ...arr2](正确,展开 arrarr2 的元素)。

  • 对象字面量中:可在任意位置展开,支持多次展开(后展开的属性会覆盖前面的重复属性)。
    例:{ x:1, ...obj, y:2, ...obj2 }(正确)。

  • 函数调用的参数中:可作为参数直接展开,位置灵活。
    例:fn(1, ...arr, 3)(正确,等价于 fn(1, arr[0], arr[1], ..., 3))。

3. 作用的目标与结果类型不同

  • rest 参数

    • 作用目标:函数接收的“多余参数”,或数组/对象中“未被解构的剩余元素”。
    • 结果类型:
      • 函数参数和数组解构中,结果是数组(即使没有元素,也是空数组 [])。
      • 对象解构中,结果是对象(即使没有属性,也是空对象 {})。
  • spread 扩展运算符

    • 作用目标:可迭代对象(数组、字符串、Set、Map 等)或普通对象(ES2018 后支持)。
    • 结果类型:本身不产生新类型,而是将目标“拆成”独立元素,用于构建新数组、新对象,或作为函数的独立参数。

总结:语法区别速查表

维度rest 参数spread 扩展运算符
核心行为收集分散元素 → 聚合为数组/对象拆分聚合对象 → 展开为独立元素
使用位置限制必须作为最后一个元素(函数参数/解构末尾)无位置限制,可在多个位置出现
结果类型数组(函数/数组解构)、对象(对象解构)无独立结果类型,仅用于展开元素
典型语法示例function fn(a, ...rest) {}[...arr1, ...arr2]fn(...args)

简单记:
rest 是“聚”,spread 是“散”
rest 是“收尾收集”,spread 是“中间/任意位置展开”。

http://www.dtcms.com/a/570582.html

相关文章:

  • 中国建站公司在线答题网站开发
  • Dinomaly2:最新多类无监督异常检测SOTA
  • 自己做片头的网站青岛网站建设外贸
  • DWG格式Web发布与GIS应用难题破解:奥维 VS GISBox
  • Git操作积累
  • 国外企业网站案例seo实战密码第三版pdf
  • 西安网站建设电话做招聘的网站有哪些
  • Ubuntu 配置临时 IP 和 VLAN
  • 如何给需求排序,确定优先级?
  • 网站开发前后端短视频营销国内外研究现状
  • 门户网站编辑流程做网站全是别人的链接
  • 智能网站系统html颜色代码
  • 做问卷调查有哪些网站网站建设后台编程
  • 4.2 路由器的组成
  • 可存储到文件里的通讯录contact
  • 【进阶版】基于Ollama和RAG,本地部署“懂业务”的大模型
  • SAP固定损耗数量或者固定用量,损耗率的方案
  • 建设部监理工程师网站有什么网站做微商
  • 做外贸网站要注意什么济南疾控最新发布
  • 【案例】UI 管理框架
  • 佛山网站建设外贸西安工商注册平台官网
  • 做网站编程要学什么中韩双语网站制作价格
  • 宁波专业的网站建设仕德伟做的网站
  • 商标设计网站猪八戒快速做效果图的网站叫什么
  • 推广网站哪家做的好文登区住房和城乡建设局网站
  • Oracle 数据库性能追踪与数据整合实践指南
  • 成都做网站公司一个完整的产品运营方案
  • 嘉兴做外贸网站的公司seo推广人员
  • 做网站需要知道哪些事情怎样做网络推广效果好视频
  • 建设网站程序忻州市中小企业局网站