??????(到底在?
Nullish Coalescing Operator ??運算子
簡單來說,一般我們在決定預設值的時候會用 || 來做短路運算:
1 2 3 4 5 6 7 8 9 10 11 12 13
| const person = { name: null, interesting: '', age: 0 }
const name = person.name || 'PeaNu' const interesting = person.interesting || 'coding' const age = person.age || 18
console.log(name) console.log(interesting) console.log(age)
|
在上面的例子因為 null、"" 和 0 都是假值,所以會套用 || 後面的預設值。
可是有些時候我們可能就是想要這些假值,這時候就可以用到 ?? 運算子了。這個東西叫做「Nullish coalescing operator」,是 ES2020(ES11) 推出的功能。
直接來看範例吧:
1 2 3 4 5 6 7 8 9 10 11 12 13
| const person = { name: null, interesting: '', age: 0 }
const name = person.name ?? 'PeaNu' const interesting = person.interesting ?? 'coding' const age = person.age ?? 18
console.log(name) console.log(interesting) console.log(age)
|
只要不是 null undefined 這些「真假值」,對 ?? 而言都是真值,所以就可以把 0 "" 這些假值給留下來。
Optional chaining operator 可選串連
這個東西主要是用來解決「存取屬性」的問題,先來看個例子:
1 2 3 4 5 6 7 8 9
| const response = { rows: [ { name: 'PeaNu' } ] }
if (response.rows[0].name === 'PeaNu') console.log('this is peanu')
|
假如我們想看第一筆資料的 name 是不是 PeaNu 的話可能就會像上面這樣子寫,可是這樣有一個問題,那就是如果今天 rows 是空的話怎麼辦?
1 2 3 4
| const response = { rows: [] } if (response.rows[0].name === 'PeaNu') console.log('this is peanu')
|
這時候就會噴 Error,跟你說 can't not read property of undefined,然後程式就掛了。
所以你可能就會改成這樣寫:
1 2 3 4
| const response = { rows: [] } if (response.rows[0] && response.rows[0].name === 'PeaNu') console.log('this is peanu')
|
利用短路運算先確認 row[0] 是有東西的才去存取 name,就能避免程式出錯。
好,這樣看起來問題是解決了,可是今天如果要存取的屬性「在很裡面」呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| const response = { rows: [ { name: 'PeaNU', age: 20, relationship: { girlFriend: 'PPB', father: 'FeaNut', mother: 'CeaNut' } } ] } if ( response.rows[0] && response.rows[0].relationship && response.rows[0].relationship.girlFriend && response.rows[0].relationship.girlFriend === 'PPB' ) console.log('peanu has girlfriend')
|
當東西越裡面時,就需要越多個 && 來做運算,有沒有更好的做法?
這時候 ? 就派上用場了,用 ? 可以改寫成這樣:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const response = { rows: [ { name: 'PeaNU', age: 20, relationship: { girlFriend: 'PPB', father: 'FeaNut', mother: 'CeaNut' } } ] } if (response.rows[0]?.relationship?.girlFriend === 'PPB') console.log('peanu has girlfriend')
|
意思跟剛剛是一樣的,他會一路從 row[0]、relationship 往下存取,只要 ? 前面的東西不存在,就會直接回傳 undefined,所以就能避免掉 Error 的問題。