前言
I don’t wanna tell you what to do, but I know it works, so I say it as plainly as I can: Just write, keep on writing.
–< Robert Birming >
持續學習,努力努力
展開/其餘運算子(Spread operator/Rest operator)
都是 Javascript ES6 中的特性,兩者的符號雖然都是 …
,
但是在使用上略有差異。
先來看看展開運算子
Spread operator
先來看一下MDN 的官方定義 Spread syntax (…)
展開語法(Spread syntax), 可以在
函數調用/數組構造
時, 將數組表達式
或者string
在語法層面展開;
還可以在構造字面量
時, 將對象Obj表達式按key-value的方式展開。
(字面量一般指[1, 2, 3] 或者{name: “mdn”} 這種簡潔的構造方式)
從定義我們可以了解到展開語法的使用場景
如下
- 函數調用
- 數組構造
- 構造字面量對象(ES2018)
消化一下原文整理 Spread syntax
的作用如下
- 展開數組
- 展開字符串
- 展開對象 (只能用於
構造字面量對象
)
在函數中調用時使用
1 | // 展開數組 |
與rest參數對比
在函數調用時使用展開語法時,需要特別注意數組
、字符串
其實是被展開成了參數序列
。
語法 | 用途 |
---|---|
其餘參數 ... |
將一個不確定數量的參數集合在一個陣列中 |
展開運算子 ... |
將陣列中的值展開為個別值 |
舉個例子:
1 | function test ( x, y, ...params ) { |
作為apply的語法糖
1 | let numArr = [ 1 , 10 , 2 , 234 ] |
在new的時候使用
因為new的時候是無法調用apply的,所以展開語法這個時候起到了很有用的腳色
先拿一個當例子
1 | function Person ( name, age, weight ) { |
這在需要生產很多個的例子時,非常有用
1 | function Person ( name, age, weight ) { |
在數組構造時使用
1 | // 展開數組 |
代替將已有數組元素插入到新數組重的所有API
以往我們將已有數組的元素插入到新數組的中,
需要藉用一些API例如push
/unshift
/splice
/concat
,
現在我們使用展開語法
可以對上述api進行替換。
需要特別強調的是,這在創建新數組
的時候才比較方便
1 | let arr = [ 4 , 5 ] |
如果是對原有
的數組進行操作,
原有API+在函數調用中使用展開語法比較方便
但通常都不建議修改原數組
實現對數組的淺拷貝 Array
1 | let obj = { a : 1 } |
在構造字面量對象時使用
實現對象的淺拷貝 Object
1 | // 1. 遍歷let newObj = {} |
使用展開語法實現
1 | let newObj2 = {...obj} //{a: '10', b: {…}, d: Array(3)} |
常見用途 — 將可迭代 (literable) 的物件轉為陣列
Javascript 中可迭代的物件有 String, Array, TypedArray, Map, Set 物件:
1 | const name = 'emma'; |
其餘運算子(Rest operator)
其餘參數之所以被創造就是要用來取代ES5的
arguments
物件
ES6之前 要將 arguments 轉為 Array
很麻煩要打很多東西,例子如下,
1 | function result(){ |
在ES6之前只有arguments物件可以使用時,可能還需要透過一些手法處理後才能使用陣列的方法,但ES6之後有了其餘參數一切都變得省事許多!
1 | function result(...a){ |
484清楚很多
常見用途 1 — 其餘參數 (Rest parameters)
用於想要傳入一個不確定數量的值給函式作為參數:須注意在傳入函式時,必須是參數中的最後一位,而且參數中只能有一個其餘參數
- 傳入多個參數:
1 | function many(x,y, ...z){ // 指定了兩個參數和一個剩餘參數 |
即使只有傳入一個值,也會被組成陣列:
如果沒有傳入值,就會成為一個空的陣列,而不是 undefined:
常見用途 2 — 解構賦值 (destructuring)
解構賦值可以想像成鏡像
的方式來進行賦值,
- 一般的解構陣列:
1 | const [a,b] = [1,2]; |
- 其餘運算子解構陣列:
1 | const [a, ...b] = [1, 2, 3]; |
- 一般解構物件:
1 | const [a, ...b] = [1, 2, 3]; |
- 其餘運算子解構物件 :
1 | let {a, b, ...rest} = { a:1, b:2, c:3, d:4 }; |
如果和其餘參數出現一樣的狀況,數量不相等時,也會成為空的陣列:
1 | let [c, ...d] = [1] |
總結與差異 Summary&Differences
展開運算子的概念可以想成是一種灑進去的感覺,
把陣列或是可迭代的物件展開成一個一個獨立的值,
再灑進使用他的地方。
而其餘運算子則是 集合剩下來的值組合成陣列`,
讓我們可以傳遞未知數量的參數至函式中