owned this note
owned this note
Published
Linked with GitHub
# ... 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