# ... Spread Operator / Rest Operator > ES6 新增了展開運算子(Spread Operator)與其餘運算子(Rest Operator)兩種新運算子, 兩者的符號都是(...)三個點,但使用的情況與意義不同。 | | Spread Operator | Rest Operator | | -------- | -------- | -------- | | 作用 | 展開陣列中的值 | 集合其餘的值成為陣列 | ### Spread Operator 展開運算符 - 連接陣列(相當於使用 `concat` ) ```javascript= const params = [ "hello", true, 7 ] const other = [ 1, 2, ...params ] // [ 1, 2, "hello", true, 7 ] ``` - 陣列的淺拷貝 ```javascript= const arr = [1,2,3] const arr2 = [...arr] arr2.push(4) //不會影響到arr ``` - 作為函式參數展開帶入(相當於 `apply` 的簡單寫法) ```javascript= function sum(a, b, c) { return a + b + c } const args = [1, 2, 3] sum(…args) // 6 ``` - 把可迭代(iterable)或與陣列相似(Array-like)的物件轉變為陣列 | 可迭代的資料類別 | | -------- | | String | | Array | | TypedArray | | Map物件 | | Set物件 | | **Array-like 物件** | ```javascript= const aString = "foo" const chars = [ ...aString ] // [ "f", "o", "o" ] ``` ### Rest Operator 其餘運算符 > 其餘運算符是收集其餘的(剩餘的)這些值,轉變成一個陣列。它會用在函式定義時的傳入參數識別名定義(其餘參數, Rest parameters),以及解構賦值時。 :::warning 在使用其餘運算符時一樣只能用一個,位置也只能放在最後一個。 ::: #### Rest parameters 其餘參數 > 其餘參數代表是將"不確定的傳入參數值們"在函式中轉變成為一個陣列來進行運算。 ```javascript= function sum(…numbers) { const result = 0 numbers.forEach(function (number) { result += number }) return result } sum(1) // 1 // number=[1] sum(1, 2, 3, 4, 5) // 15 // number=[1,2,3,4,5] sum() // 15 // number=[] ``` #### Destructuring 解構賦值 > 解構賦值是用在"陣列指定陣列"或是"物件指定物件"的情況下,這個時候會根據陣列原本的結構,以類似"鏡子"對映樣式(pattern)來進行賦值。 > - 用於提取(extract)**陣列**或**物件**中的資料,過去要做到這件事可能需要使用迴圈或迭代的語句。 - 陣列解構 ```+ //基本用法 const [a, b] = [1, 2] //a=1, b=2 //先宣告後指定值,要用let才行 let a, b [a, b] = [1, 2] // 略過某些值 const [a, , b] = [1, 2, 3] // a=1, b=3 // 其餘運算 const [a, ...b] = [1, 2, 3] // a=1, b=[2,3] // 失敗保護(Fail-safe) const [, , , a, b] = [1, 2, 3] // a=undefined, b=undefined // 交換值 const a = 1, b = 2; [b, a] = [a, b] //a=2, b=1 // 多維複雜陣列 const [a, [b, [c, d]]] = [1, [2, [[[3, 4], 5], 6]]] // 字串 const str = "hello"; const [a, b, c, d, e] = str ``` - 物件解構 ```+ // 基本用法 const { user: x } = { user: 5 } // x=5 // 失敗保護(Fail-safe) const { user: x } = { user2: 5 } // x=undefined // 賦予新的變數名稱 const { prop: x, prop2: y } = { prop: 5, prop2: 10 } // x=5, y=10 // 屬性賦值語法 const { prop: prop, prop2: prop2 } = { prop: 5, prop2: 10 } // prop = 5, prop2=10 // 相當於上一行的簡短語法(Short-hand syntax)!!! const { prop, prop2 } = { prop: 5, prop2: 10 } // prop = 5, prop2=10 // ES7+的物件屬性其餘運算符!!! const {a, b, ...rest} = {a:1, b:2, c:3, d:4} // a=1, b=2, rest={c:3, d:4} ``` - 其他的資料類型解構 >原始解構值是 `null` 或 `undefined` 時,會得到錯誤。 ```+ const [a] = undefined const {b} = null //TypeError: Invalid attempt to destructure non-iterable instance ``` >原始資料類型布林、數字、字串等作物件解構,則會得到undefined值。 ```+ const {a} = false const {b} = 10 const {c} = 'hello' console.log(a, b, c) // undefined undefined undefined // 未能成功解構 ``` >解構賦值的預設值 ```+ const [missing = true] = [] console.log(missing) // true const { message: msg = 'Something went wrong' } = {} console.log(msg) // Something went wrong const { x = 3 } = {} console.log(x) // 3 ``` --- ### 參考資料: https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/Spread_syntax https://eyesofkids.gitbooks.io/javascript-start-from-es6/content/part4/rest_spread.html https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Functions/rest_parameters https://eyesofkids.gitbooks.io/javascript-start-from-es6/content/part4/rest_spread.html