rest 的意思就是"剩下的"。用 ...args 把函数调用时剩下的实参,打包成一个数组。
| 以前 · arguments | 现在 · rest |
|---|---|
function data() {
console.log(arguments);
}
data("大哥", "二哥", "三哥");
// {0:"大哥",1:"二哥",2:"三哥",length:3}
|
function data(...args) {
console.log(args);
}
data("大哥", "二哥", "三哥");
// ["大哥","二哥","三哥"]
|
以前只能用 arguments 拿,但它"像数组又不是数组"(叫类数组),用起来别扭;rest 直接给你一个真数组,[] 括起来,清清楚楚。
| 以前 · 用不了数组方法 | 现在 · 数组方法随便用 |
|---|---|
function data() {
arguments.map(x => x); // 报错!
}
data("大哥", "二哥");
// 报错:arguments.map is not a function
|
function data(...args) {
console.log(args.map(x => x + "!"));
}
data("大哥", "二哥");
// ["大哥!", "二哥!"]
|
类数组就像"长得像苹果的塑料苹果"——看着像数组,但数组的方法(map / filter / push)一个都用不了。rest 给的是真苹果,想怎么用怎么用。
| 以前 · 手动挑剩下的 | 现在 · rest 自动收 |
|---|---|
function data(a, b) {
let rest = [];
for (let i = 2; i < arguments.length; i++) {
rest.push(arguments[i]);
}
console.log(rest);
// ["三哥","四哥"]
}
data("大哥","二哥","三哥","四哥");
|
function data(a, b, ...rest) {
console.log(rest);
// ["三哥","四哥"]
}
data("大哥","二哥","三哥","四哥");
|
前两个参数 a、b 先拿走,剩下的自动全进 rest 数组。... 永远收"别人挑剩下的"。
用法一:求一堆数的和(传几个都行)
| 以前 | 现在 |
|---|---|
function sum() {
let total = 0;
for (let i = 0; i < arguments.length; i++) {
total += arguments[i];
}
return total;
}
console.log(sum(1, 2, 3, 4)); // 10
|
function sum(...nums) {
let total = 0;
for (let n of nums) total += n;
return total;
}
console.log(sum(1, 2, 3, 4)); // 10
|
用法二:把参数拼成一个字符串
| 以前 · 要先转数组 | 现在 · 直接 join |
|---|---|
function joinAll() {
let arr = Array.prototype.slice.call(arguments);
return arr.join(" - ");
}
console.log(joinAll("A","B","C","D"));
// A - B - C - D
|
function joinAll(...args) {
return args.join(" - ");
}
console.log(joinAll("A","B","C","D"));
// A - B - C - D
|
rest 本来就是数组,join 直接用;arguments 还得先"变"成数组,多一步。
① ...rest 必须放在最后一个位置,后面不能再有参数:
function data(a, ...rest, b) {} // 报错
function data(a, ...rest) {} // 正确
② 箭头函数没有 arguments,想拿参数就用 rest:
let data = (...args) => console.log(args); data(1, 2, 3); // [1,2,3]