解構賦值(Destructuring Assignment)
基本說明
簡單來說,可以想像是鏡子的概念,將右方的資料往左邊送,然後會一個位置對一個值。
- 陣列 ==對應=> 順序的索引值
- 物件 ==對應=> 物件的屬性名稱
陣列解構賦值
基本用法
1 | //ES5 |
陣列各種情境
當變數的數量多於賦予的值時,多出來的那個變數會被賦予 undefined
的值(d = undefined):
1 | // 變數 多於 所給的值 |
當輸入的變數少於所給的值的時候,只有被指定到的變數會有值,少掉的變數可以直接空過去:
1 | // 當變數 少於 所給的值 |
至於陣例傳值是有順序性,在這個範例中直接將右邊的變數交換到左邊,可以看到是同時交換變數,所以在互換變數值時是非常方便的。
1 | // 交換值 |
遇到字串則會將字串拆解成一個一個字元,賦予到左方的變數上。
1 | let str = 'kanboo'; |
另外也可以運用 ES6 的其餘參數 ,可以看到有個 ...other
的用法 ,這是可以將剩餘的陣列成員通通塞給 other 這個變數,如果沒有相對應的值則這個變數的值會是undefined
,
1 | let [one, ...other] = [1, 2, 3, 4]; |
物件解構賦值
陣列是使用順序的索引值對應,但物件則是使用物件的屬性名稱來做對應(因此沒有順序性)。
在以下範例則是快速將物件值解構在變數上。
1 | // 基本用法 |
如果變數與屬性名都沒有對應的名稱,則變數的值會是 undefined
1 | // 沒有對應的屬性 |
而物件的解構方法,還能重新賦予變數的名稱,也可以屬性值來當作變數對應等號後方的屬性值,寫法會是類似這樣:
1 | const { user: aa, admin: zz } = { user: '平民', admin: '皇帝' }; |
不可行的寫法
和陣列解構賦值不同的是,在陣列解構賦值中,我們可以接受 「變數 少於 所給的值 」:
1 | let [a, , c] = [1, 2, 3]; |
但是在物件解構賦值中,我們不能像上面這樣寫:
1 | let{a, ,c} = {a:1, b:2, c:3}; |
只能接受 「變數 多於 所給的值 」
1 | let { a, b, c, d } = { a: 1, c: 3 }; |
物件解構賦值的用途
物件解構賦值的用途相當多,其中在提取 JSON
數據時相當方便:
1 | let ajax_JSON = { |
延伸上例,若我只想取得 other 裡的「電話 tel」,取得方式,如下例
1 | let ajax_JSON = { |
如此就能夠快速取得 JSON
物件的屬性名和屬性值。
混合使用
複雜的物件或混合陣列到物件,如果你能記住之前說的鏡子樣式對映基本原則,其實也很容易就能理解
1 | let { |
1 | // 複雜多層次的物件 |
預設值
除了使用鏡射的概念外,為了避免值沒有賦予造成 undefined
,可以使用預設值避免此問題。
如以下左方的陣列都先賦予的預設值,當右方的陣列只有一個值時,左方的陣列剩餘內容將會採用預設值。
1 | const [isPass = true] = []; |
要作一個簡單的陷阱題滿簡單的,你可以試看看下面這個範例中到底是賦到了什麼值:
1 | const { a = 'kanboo' } = 'hello'; |
函式
除了以上的方法外,解構也能使用在函式的參數,使用方式如同將傳入的物件對應到函式參數上。
這樣參數一樣能夠能夠自訂變數名稱、順序、預設值等。
1 | function func({ a = 3, b }) { |
當 a 與 b 兩個都有預設值時,NaN
的情況不存在:
1 | function func({ a = 3, b = 5 }) { |
實際上函式傳入參數它自己也可以加預設值,但這情況會讓最後一種 func()
呼叫時與 func({})
相同結果:
1 | function func({ a = 3, b = 5 } = {}) { |
另一種情況是在函式傳入參數的預設值中給了另一套預設值,這只會在 func()時發揮它的作用:
1 | function func({ a = 3, b = 5 } = { a: 7, b: 11 }) { |