前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库rest 剩余参数与 arguments 区别
JSJavaScript函数与作用域

JavaScript 剩余参数(rest parameters)与 arguments 对象相比有哪些优势?

剩余参数是真正的数组,可直接调用数组方法;arguments 是类数组对象,需转换后才能使用数组方法。此外剩余参数只收集未命名参数,语义更清晰。

前端进阶之旅 · 一题精讲更新于 2026.09.05
JavaScript#函数与作用域
先看核心答案读代码示例
理解线索

剩余参数:显式的实参收集器

  1. 真数组可直接调用 sort、map 等数组方法
  2. 仅收多余排除已命名参数,只包剩余实参
  3. 无 callee不暴露已废弃的 callee 属性

箭头函数没有 arguments,但剩余参数在箭头函数中照常工作。

核心回答

先记住这个答案

剩余参数(...args)将额外实参收集为真正的 Array 实例,可直接使用 map、filter 等方法;arguments 是类数组对象,必须先用 Array.from 或展开符转换。剩余参数只包含未被命名参数占用的实参,且不包含 callee 属性;而 arguments 包含全部实参(包括已命名部分),且与非严格模式下的简单参数存在索引同步。

  • 剩余参数是数组,arguments 是类数组
  • 剩余参数只收未命名参数,arguments 包含全部
  • 剩余参数必须放最后且只能一个

数组性与收集范围的机制差异

函数声明 function f(a, ...rest) 会把从第二个实参开始的所有值放入名为 rest 的真实数组。这个数组继承自 Array.prototype,因此 rest.map、rest.sort 可直接调用,无需 Array.prototype.slice.call 这类样板代码。arguments 是类数组对象,它虽然有 length 和索引,但不继承 Array.prototype,没有 sort、map 等数组修改方法,直接调用 arguments.sort 会抛出 TypeError。

另一个关键是收集范围。arguments 包含调用时传入的全部实参,包括已命名参数对应的值;而剩余参数只收集位于命名参数之后的那些实参。例如 function f(a, ...bs) 调用 f(1,2,3) 时,arguments[0] 是 1,bs 是 [2,3]。这种差别使剩余参数语义更聚焦:明确区分“已知参数”和“可变部分”,避免在函数体内再通过索引跳过固定参数。

对比剩余参数与 arguments 的数组性JavaScript
function diff(a, ...rest) {
  console.log('rest is array?', Array.isArray(rest));
  console.log('arguments is array?', Array.isArray(arguments));
  console.log('rest length', rest.length);
  console.log('arguments length', arguments.length);
  console.log('sort works?', rest.sort()[0], typeof arguments.sort);
}
diff(3, 1, 2);
查看输出与解释
rest is array? true
arguments is array? false
rest length 2
arguments length 3
sort works? 1 undefined

运行显示剩余参数是数组,arguments不是。arguments.sort 是 undefined,因为对象没有数组方法。

构造累加器:避免转换样板代码

假设需要实现一个计算任意数量数字总和的函数,但要求跳过第一个参数作为基数。用剩余参数可以这样写:function sumFrom(base, ...nums) { return nums.reduce((acc, n) => acc + n, base); }。调用 sumFrom(100, 1, 2, 3) 返回 106。这里 nums 直接是数组,能立即调用 reduce,代码直观。

若改用 arguments,必须先取出基数和剩余部分:function sumFrom(base) { var args = Array.prototype.slice.call(arguments, 1); return args.reduce(...); } 或者用 Array.from(arguments).slice(1)。额外转换步骤不仅啰嗦,还容易忘记索引偏移导致取错参数。剩余参数让代码表达“可变部分”的意图,减少出错风险。

语法限制和参数别名同步问题

剩余参数有限制:必须作为最后一个形参;一个函数只能有一个;不能有默认值。这些限制在语法层面就约束了不合理用法。但 arguments 没有任何位置限制,可以出现在任意位置,而且在非严格模式下,简单参数的 arguments 索引值会与命名参数保持同步——修改 arguments[0] 会改变 a,反之亦然。这种隐式同步容易让人困惑,而剩余参数是每次调用时独立创建的数组,不会与命名参数同步。

当函数需要同时使用默认参数或解构时,剩余参数的语法限制可能带来额外注意。例如 function f(a = 1, ...rest) 是合法的,但 function f(...rest, a) 会报错。如果确实需要处理“前若干参数不定、后有固定参数”的情况,剩余参数无法直接表达,只能用 arguments,然后在内部通过长度判断。这时应权衡:追求代码一致性时优先用剩余参数,但遇到非尾部的集合收集时,arguments 仍是必要工具。

回答前,多想一步

容易答错的地方

认为 arguments 可以像数组一样调用方法
直接写 arguments.map(...) 会报 TypeError,因为 arguments 是类数组对象,不继承 Array 原型。必须用 Array.from(arguments) 或展开符转换后才能使用数组方法。
认为剩余参数包含所有实参
剩余参数只包含未被命名参数占用的部分。若函数定义 function f(a, ...rest),调用 f(1,2,3) 时 rest 是 [2,3],不包含 1。而 arguments 包含全部三个值。两者长度不一定相等。
试着用自己的话回答

面试官还会怎么问?

剩余参数可以解构吗?

可以。比如 function f(...[a, b]) 会丢弃第三个及以后的实参,但这种方式与参数绑定语义混合,可读性差,实际中多用整体数组再解构。

默认参数与剩余参数能共存吗?

能,但剩余参数必须最后。例如 function f(a = 5, ...rest) 合法,这表示如果第一个实参未传则用默认值。注意剩余参数本身没有默认值语法。

箭头函数中如何使用 arguments?

箭头函数没有 arguments 对象,但可以用剩余参数收集参数。若必须用 arguments,则需在外层包装普通函数。

从一道题,走向一组知识

把知识连起来

函数与作用域

JavaScript 中 arguments 对象与函数参数(parameters)有何区别?

同属「函数与作用域」专题,接着看 arguments 与形参(parameters)的区别 在具体场景中的处理方式。

函数与作用域

如何将函数内的 arguments 对象转换为真正的数组?各方法有何不同?

同属「函数与作用域」专题,接着看 arguments 转数组的方法对比 在具体场景中的处理方式。

放回知识体系中复习JavaScript 进阶知识

参考资料

  • Rest parameters

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 数组性与收集范围的机制差异
  3. 构造累加器:避免转换样板代码
  4. 语法限制和参数别名同步问题
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑