rest參數 ...
ES6 引入 rest 參數(形式為
...變量名
),用于擷取函數的多餘參數,這樣就不需要使用
arguments
對象了。rest 參數搭配的變量是一個數組,該變量将多餘的參數放入數組中。
function add(...values) {
let sum = 0;
for (var val of values) {
sum += val;
}
return sum;
}
add(2, 5, 3) // 10
上面代碼的
add
函數是一個求和函數,利用 rest 參數,可以向該函數傳入任意數目的參數。
下面是一個 rest 參數代替
arguments
變量的例子。
// arguments變量的寫法
function sortNumbers() {
return Array.prototype.slice.call(arguments).sort();
}
// rest參數的寫法
const sortNumbers = (...numbers) => numbers.sort();
上面代碼的兩種寫法,比較後可以發現,rest 參數的寫法更自然也更簡潔。
rest參數注意點:
rest 參數之後不能再有其他參數(即隻能是最後一個參數),否則會報錯。
// 報錯
function f(a, ...b, c) {
// ...
}
擴充運算符 ...
擴充運算符(spread)是三個點(
...
)。它好比 rest 參數的逆運算,将一個數組轉為用逗号分隔的參數序列。
console.log(...[1, 2, 3])
// 1 2 3
console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
[...document.querySelectorAll('div')]
// [<div>, <div>, <div>]
Math.max(...[14, 3, 77])
// 找到數組中最大值
該運算符主要用于函數調用。
function push(array, ...items) {
array.push(...items);
}
function add(x, y) {
return x + y;
}
const numbers = [4, 38];
add(...numbers) // 42
上面代碼中,
array.push(...items)
和
add(...numbers)
這兩行,都是函數的調用,它們都使用了擴充運算符。該運算符将一個數組,變為參數序列。
擴充運算符與正常的函數參數可以結合使用,非常靈活。
function f(v, w, x, y, z) { }
const args = [0, 1];
f(-1, ...args, 2, ...[3]);
擴充運算符後面還可以放置表達式。
const arr = [
...(x > 0 ? ['a'] : []),
'b',
];
擴充運算符的應用
(1)複制數組
擴充運算符提供了複制數組的簡便寫法。
const a1 = [1, 2];
// 寫法一
const a2 = [...a1];
// 寫法二
const [...a2] = a1;
上面的兩種寫法,
a2
都是
a1
的克隆。
(2)合并數組
擴充運算符提供了數組合并的新寫法。
const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];
// ES5 的合并數組
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
// ES6 的合并數組
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]
不過,這兩種方法都是淺拷貝,使用的時候需要注意。
const a1 = [{ foo: 1 }];
const a2 = [{ bar: 2 }];
const a3 = a1.concat(a2);
const a4 = [...a1, ...a2];
a3[0] === a1[0] // true
a4[0] === a1[0] // true
上面代碼中,
a3
和
a4
是用兩種不同方法合并而成的新數組,但是它們的成員都是對原數組成員的引用,這就是淺拷貝。如果修改了原數組的成員,會同步反映到新數組。
(3)與解構指派結合
擴充運算符可以與解構指派結合起來,用于生成數組。
// ES5
a = list[0], rest = list.slice(1)
// ES6
[a, ...rest] = list
下面是另外一些例子。
const [first, ...rest] = [1, 2, 3, 4, 5];
first // 1
rest // [2, 3, 4, 5]
const [first, ...rest] = [];
first // undefined
rest // []
const [first, ...rest] = ["foo"];
first // "foo"
rest // []
如果将擴充運算符用于數組指派,隻能放在參數的最後一位,否則會報錯。
const [...butLast, last] = [1, 2, 3, 4, 5];
// 報錯
const [first, ...middle, last] = [1, 2, 3, 4, 5];
// 報錯
(4)字元串
擴充運算符還可以将字元串轉為真正的數組。
[...'hello']
// [ "h", "e", "l", "l", "o" ]