拆拆拆!
喜歡拆禮物嗎?
展開運算子(Spread-Operator),把東西給展開,可以想像是拆禮物的那種感覺 \(•ㅂ•)/
原本你在一個 array 裡面放另外一個 array 會變成二維 array:
1 | const arr = [1, 2, 3] |
但「展開運算子」會直接把內容給展開(打開):
1 | const arr = [1, 2, 3] |
可以想像成是把 [1, 2, 3]
的方括號拿掉的感覺。
搭配 function 還有一個很特別的玩法:
1 | function add(a, b, c) { |
不好懂的話,想成這樣就好理解多了:
1 | function add(a, b, c) { |
object 也可以展開:
1 | let obj = { |
但要注意一下順序的問題,如果有重複的內容,後面的會蓋掉前面的:
1 | let obj = { |
利用展開運算子拷貝 array 或 object
以往我們用 arr1 = arr2
的方式會因為變數的儲存機制導致我們存到的是「記憶體位址」而不是實際上的值。
但改用展開運算子就可以做到複製的動作:
array:
1 | const arr1 = [1, 2, 3] |
object:
1 | const obj1 = {name: 'PeaNu'} |
但是,如果是要複製的 array 跟 object是「巢狀結構」的話要特別注意:
1 | const nestedArray = [4] |
你可以把展開運算子想成是「它只能打開第一層」的這種概念,當我們用 arr2 = [...arr1]
的時候,arr1 的第一層會被拆開,變成 1, 2, 3
:
1 | const arr2 = [...arr1] |
但是 nestedArray
因為是第二層,所以不會被拆開:
1 | const arr2 = [...arr1] |
所以 arr1
跟 arr2
裡面的 nestedArray
都沒有被拆開,等於裡面放的都是「同一個 nestedArray
」,所以 arr2[3] === arr1[3]
才會等於 true。
object 也會有一樣的行為,簡單做個示範:
1 | const nestedObj = { age: 20 } |
一樣想成這樣子就好:
1 | const nestedObj = { age: 20 } |
背後的原理
以物件來說的話,其實是用 Object.assign
來實現的:
1 | const obj = { a: 1 }; |
換成 ES6 寫法就是:
1 | const obj = { a: 1 }; |