JavaScript ES6 - Spread and Rest

在學習 Vue 的途中,偶然遇見了 ES6 的展開運算符 (Spread Operator) 與其餘運算符 (Rest Operator)。
雖然 Spread 與 Rest 這兩種特性的符號都是三個點,但是使用情況與意義是不同的,在此做個筆記方便複習啦。

展開運算符 (Spread Operator)

簡單來說,就是將陣列的值一個個取出來,再一個個塞回去。

通常我們會使用展開運算符的語法來 “合併” 陣列。

範例:

1
2
3
4
let groupA = ['小明', '杰倫', '阿姨'];
let groupB = ['老媽', '老爸'];
let groupAll = [...groupA, ...groupB];
console.log(...groupA);

這樣就成功地把兩個陣列合併、接合在一起囉!

觀念說明:類陣列 (Array-Like)

當然我們剛才也可以使用陣列的 .concat() 方法來串接兩個陣列,不過有時候我們無法使用 .concat() 方法。

Node List

下方範例中,回傳的是一個 Node List,它長得跟陣列很像,但是是不一樣的東西。

1
2
let doms = document.querySelectorAll('li');
console.log(doms);

像這種由 querySelectorAll 方法回傳的 “類似陣列” 的物件,我們稱它為 Node List。

這種資料結構也可稱為「類陣列」,因為他們與陣列長得很相似,卻不能使用陣列的方法。

我們有很多時候,需要把 Node List 轉換為陣列,轉換的方法就會使用到 “展開運算符”。

將 “類陣列” 轉換為 “陣列”

1
2
3
let doms = document.querySelectorAll('li');
let newDoms = [...doms];
console.log(newDoms, doms);

第一個回傳的 newDoms 是陣列,第二個回傳的 doms 是類陣列。
前者可使用 concat()
後者因為是類陣列,而非陣列,因此不能用 concat()

觀念說明:淺複製 (Shallow Copy)

陣列與物件一樣都是 “傳參考”,因此兩個陣列的 “參考” 一樣時,兩者的值會一起變動。

1
2
3
4
let groupA = ['小明', '杰倫', '阿姨'];
let groupB = groupA; // 將 B 指向 A
groupB.push('阿明');
console.log(groupA);

上方範例中,groupA 的值會等於 groupB,因為 A 與 B 的參考相同。

該如何解決這個問題呢?

這時候我們可以使用 “展開運算符” 來處理!

1
2
3
4
let groupA = ['小明', '杰倫', '阿姨'];
let groupB = [...groupA];
groupB.push('阿明');
console.log(groupA);

透過展開運算符 ...,我們將 groupA 的值一個一個取出來,並放入一個 “新的” 陣列內。

因為這是 “傳值”,而非傳參考,因此 groupA 不受影響,這個就是「淺複製」的觀念。

其餘運算符 (Rest Operator)

1
2
3
4
function moreMoney(money) {
console.log(money);
}
moreMoney(100, 100, 200);

上方範例,我們有許多參數要帶入函式,除了命名數個參數以外,還有其他方法嗎?

はい、あります。

我們可以使用「其餘運算符」一口氣將參數傳入!
加上點點點 ...,就能讓 money 成為其餘參數。

1
2
3
4
function moreMoney(...money) {
console.log(money); // 將多餘的參數以陣列呈現
}
moreMoney(100, 100, 200);

如果有其他格式的資料,像是字串要傳入,也是沒問題的喔!

1
2
3
4
function moreMoney(ming, ...money) {
console.log(ming, money);
}
moreMoney('小明', 100, 100, 100, 1234, 5678);

特別注意

  1. “其餘參數” 是將剩餘的參數全部傳入,因此必須放在 “最右邊” 才能運作
  2. 一次只能有 “一個” 其餘參數
  3. 將多餘的參數以陣列呈現
  4. 參數無數量限制

懶人包

最後簡單整理一下內容:

  1. 兩種運算符的符號都是三個點 ...
  2. 兩者都與陣列有關
  3. 一個是 “展開” 陣列中的值,一個是 “集合” 其餘的值成為陣列

以上資源是我自己整理過後的筆記,若有錯誤歡迎隨時和我聯繫。