rest 参数是现代标准,arguments 是历史遗留;rest 是真数组、支持类型标注和解构,arguments 是类数组、需转换且不兼容箭头函数与严格模式。

Rest 参数和 arguments 都能拿到函数调用时“多出来的”实参,但它们根本不在同一设计层级上——一个是语法层明确定义的参数,一个是运行时隐式注入的对象。
类型与可用性:真数组 vs 类数组
rest 是标准 Array 实例,自带 map、filter、includes、解构、展开等全部能力,直接用不绕路。
-
function sum(nums) { return nums.reduce((a, b) => a + b, 0); }——nums可直接reduce -
function sum() { return Array.from(arguments).reduce(...); }——arguments必须先转数组才能操作 -
arguments不是数组:Array.isArray(arguments)返回false,arguments instanceof Array也是false
作用域与函数类型限制
rest 是显式声明的形参,存在于所有函数中(包括箭头函数),而 arguments 只在 function 声明的非箭头函数里自动存在。
- 箭头函数中访问
arguments会向上查找外层函数,容易出错或返回undefined -
rest在箭头函数中完全正常:const log = (prefix, ...msgs) => msgs.forEach(m => console.log(`${prefix}: ${m}`)); - 严格模式下,
arguments与形参不再双向同步,行为更不可控
语义清晰度与工程实践
rest 名字可自定义、位置固定(必须在参数列表末尾)、意图明确;arguments 没有声明、没有类型、IDE 和 TypeScript 无法推导,导致 any 泛滥。
-
function greet(lang, ...names)—— 一眼看出前一个是语言,后面全是人名 -
function greet() { const [lang, ...names] = arguments;—— 需手动切片,且arguments[0]类型为any -
rest支持默认值、解构、类型标注(TS 中可写...ids: number[]),arguments完全不支持
性能与维护成本
V8 等现代引擎对 rest 有专门优化,而 arguments 会触发某些优化禁用机制(如内联失败),还可能拖慢 JIT 编译。
-
arguments存在历史包袱:callee、caller在严格模式下禁用,兼容性差 - 团队代码中每多一个
arguments,就多一处类型盲区和潜在运行时错误 - 除极老环境(如 IE11 以下)或特殊代理场景外,已无理由继续使用
arguments











