← 返回目录

7. rest 参数

rest 直译就是"剩下的"。用 ...args 把调用时没人点名要的实参,全部打包成一个真数组收进来,替代又绕又不是真数组的 arguments

7.1 互动演示(传几个都行)

改数字点按钮,看 rest 怎么收"剩下的"。

7.2 知识点讲解

① 没有 rest 时:arguments 又绕又不是数组

以前函数里想拿"传进来的所有参数",得用 arguments——它长得像数组(有 length、能按下标取),但其实是"类数组",map/filter/push 这些数组方法一个都用不了

// 以前:arguments 是"类数组"
function data() {            // 没写参数
  console.log(arguments);    // 用 arguments 收全部实参
}
data("大哥", "二哥", "三哥"); // 传三个
// {0:"大哥",1:"二哥",2:"三哥",length:3} —— 不是真数组!

// 现在:...args 直接给真数组
function data(...args) {     // ... 把所有实参打包成真数组
  //      ^^^^^ 把剩下的全部打包成数组
  console.log(args);         // 直接打这个真数组
}
data("大哥", "二哥", "三哥"); // 传三个
// ["大哥","二哥","三哥"]  ← 真数组,想怎么用怎么用

类数组 = 长得像数组、但 map/filter/push 全不能用,得先 Array.from(arguments) 转一遍。...args 给的是真数组,省了这一步。

② 收集"剩下的"参数

参数列表里前面几个是"点名要的",... 永远收"别人挑剩下的"。

// 前两个参数 a、b 先被点名拿走,剩下的全进 rest
function data(a, b, ...rest) { // a、b 点名拿前两个,...rest 收剩下的
  //      ↑  ↑ ^^^^^^^ 剩下的打包
  console.log(rest);            // 只打剩下的
}
data("大哥", "二哥", "三哥", "四哥"); // 传四个
// ["三哥","四哥"]  ← 前两个被 a、b 拿走,剩下两个进 rest

如果你把 ...rest 写在参数列表中间(比如 function f(a, ...rest, b)),浏览器会直接报错。因为它要收"剩下的",后面不能再有别的参数了——rest 必须永远放最后一位。

③ 常见用法:求和 / join

// 求一堆数的和(传几个都行)
function sum(...nums) {       // ...nums 把所有数收进真数组
  let total = 0;              // 累加器从 0 开始
  for (let n of nums) total += n; // nums 是真数组,直接 for...of
  return total;               // 返回总和
}
console.log(sum(1, 2, 3, 4)); // 10

// 拼成字符串:rest 是数组,join 直接用
function joinAll(...args) {   // 收所有实参成真数组
  return args.join(" - "); // 真数组才有 join
}
console.log(joinAll("A", "B", "C")); // 传三个
// A - B - C

④ 箭头函数没有 arguments,只能靠 rest

// 箭头函数里根本没有 arguments 这个变量
let data = (...args) => console.log(args); // 箭头函数只能用 rest 收参数
//     ^^^^^^ 只能用 rest 收参数
data(1, 2, 3); // [1,2,3]

7.3 实战:用在哪 / 常见坑 / 怎么解决

① 可能在什么地方用:写不定参数的工具函数(sum(...nums)min(...nums))、事件回调里收全部参数、箭头函数里想拿全部参数(因为没有 arguments)。

② 常见的问题:...rest 放中间导致语法报错;把 rest 和 arguments 混用;以为 rest 能拿到"已经点名的参数"。

③ 解决思路:rest 永远放最后;箭头函数里用 ...args 代替 arguments;需要全参数就一个 ...args,需要前几个就点名 + rest 组合。

一句话:...rest = 把剩下的实参打包成真数组,放最后一位,箭头函数里全靠它。