Spread Operator / Rest Operator

ES6 新增了展開運算子(Spread Operator)與其餘運算子(Rest Operator)兩種新運算子,
兩者的符號都是()三個點,但使用的情況與意義不同。

Spread Operator Rest Operator
作用 展開陣列中的值 集合其餘的值成為陣列

Spread Operator 展開運算符

  • 連接陣列(相當於使用 concat )
const params = [ "hello", true, 7 ] const other = [ 1, 2, ...params ] // [ 1, 2, "hello", true, 7 ]
  • 陣列的淺拷貝
const arr = [1,2,3] const arr2 = [...arr] arr2.push(4) //不會影響到arr
  • 作為函式參數展開帶入(相當於 apply 的簡單寫法)
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 物件
const aString = "foo" const chars = [ ...aString ] // [ "f", "o", "o" ]

Rest Operator 其餘運算符

其餘運算符是收集其餘的(剩餘的)這些值,轉變成一個陣列。它會用在函式定義時的傳入參數識別名定義(其餘參數, Rest parameters),以及解構賦值時。

在使用其餘運算符時一樣只能用一個,位置也只能放在最後一個。

Rest parameters 其餘參數

其餘參數代表是將"不確定的傳入參數值們"在函式中轉變成為一個陣列來進行運算。

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}
  • 其他的資料類型解構

原始解構值是 nullundefined 時,會得到錯誤。

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

Select a repo