JavaScript 來看看神奇的 ? 跟 ?? 運算子

??????(到底在?

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) // 'PeaNu'
console.log(interesting) // 'coding'
console.log(age) // 18

在上面的例子因為 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) // 'PeaNu'
console.log(interesting) // ""
console.log(age) // 0

只要不是 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 的問題。

從零開始建立一個 React 開發環境 mentor-program-day132
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×