展開運算子 / 其餘運算子 (spread operato / rest operator) 都是寫成 ...
,但使用上略有差異。
展開運算子 spread operator
類似 concat() 用法
以前要將 2 個陣列合併我們會用 concat()
:
const ary1 = [1, 2];
const ary2 = [3, 4];
const newAry = ary1.concat(ary2); // [1,2,3,4]
透過使用展開運算子 ...
我們除了縮短程式碼,也變得更容易閱讀:
const ary1 = [1, 2];
const ary2 = [...ary1, 3, 4]; // [1,2,3,4]
// 多個陣列合併
const newAry = [....ary1, ...ary2]; // [1,2,3,4]
將陣列展開傳入 function
在之前,如果想將陣列展開代入 function 參數的話,會用 apply()
:
const ary = [1, 2];
function showNum(a, b){
console.log('a: '+a, 'b: '+b);
};
showNum.apply(null, ary); // "a: 1" "b: 2"
使用展開運算子就會變得方常方便並且好閱讀:
const ary = [1, 2];
function showNum(a, b){
console.log('a: '+a, 'b: '+b);
};
showNum(...ary); // "a: 1" "b: 2"
將可迭代 (literable) 的資料型別與類陣列(array-like)轉為陣列
在 JS 中可迭代 (literable) 的資料型別為:
- Array
- TypeArray
- String
- Map
- Set
- arguemtns
- DOM Elements
const str = 'Hello'
const strAry = [...str]; // ["H","e","l","l","o"]
// 將類陣列(array-like)轉為陣列
const els = document.querySelectorAll('p'); // 此為類陣列
els = [...els];
物件擴展
展開運算子也可以用於物件上,當我們想在某一個物件裡合併其他物件時:
const fnObj = {
sayHi() {
console.log('Hi');
},
};
const newFnObj = {
sayHello() {
console.log('Hello');
},
...fnObj // 將 fnObj 拷貝過來
};
/*
{
sayHello() {
console.log('Hello');
},
sayHi() {
console.log('Hi');
}
};
*/
淺拷貝(shallow copy)物件與陣列
接續上面所介紹的展開陣列與物件擴展,物件與陣列與物件因為傳參考(Call By Reference)的特性的關係,當我們把這 2 種資料賦予到其他的變數上時,修改其中一個陣列或物件裡的值,另一個也會隨之變動,展開運算子是一個個將值寫入,因此也可以拿來做淺拷貝。
const fnObj = {
sayHi() {
console.log('Hi');
},
};
const newFnObj = {
sayHello() {
console.log('Hello');
},
...fnObj // 將 fnObj 的內容淺拷貝過來
};
newFnObj.sayHi = 'Hi';
console.log(fnObj.sayHi); // ƒ sayHi() {console.log('Hi');}
console.log(newFnObj.sayHi); // 'Hi'
其餘運算子(其餘參數)rest operator
...
作為其餘運算子時又可以稱為其餘參數,作用如同其名,在宣告 funtion 時如果不確定會代入多少參數就可以使用其餘參數。
其餘參數有點類似 arguments
,它也會回傳一個參數陣列,但它們有以下幾點不同:
- 其餘參數是真的陣列(可以使用陣列所有語法),而
arguments
不是。 - 其餘參數可以自己決定從哪個位置的參數開始算起,而
arguments
會將所有傳入 function 的參數都傳入arguments
的陣列裡。 - 其餘參數可以字定義變數名稱,而
arguments
不能。
// 其餘參數寫法 ...變數名稱
function addUp(...num){
return num.reduce((acc, cur) => acc + cur, 0);
};
addUp(1, 2, 3, 4, 5); // 15
// 與其他參數混用
function updateTotal(curMoney, ...depositMoney){
return depositMoney.reduce((acc, cur) => acc + cur, curMoney);
};
updateTotal(500, 1100, 200, 50, -100); // 1750
在其餘參數出來後,現在 arguments
基本上都被其餘參數所取代。