Optional Chaining (可選串連)

使用情境

假設今天有一些資料長這樣:

1
2
3
4
5
6
7
8
9
10
11
12
const users = [
{
name: 'Blueberry',
github: {
account: 'B-l-u-e-b-e-r-r-y',
url: 'https://github.com/B-l-u-e-b-e-r-r-y'
}
}, {
name: 'Foo',
github: null
}
]

然後我想要用 map 取得 User 的 Github 帳號——

1
users.map(user => user.github.account);

因為 Foo 的 github 為 null,所以會報錯:

Cannot read property ‘account’ of null

當然,也可以改成這樣:

1
users.map(user => user.github && user.github.account);

但如果今天的資料格式變成了……

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
const users = [
{
name: 'Blueberry',
github: {
account: 'B-l-u-e-b-e-r-r-y',
url: 'https://github.com/B-l-u-e-b-e-r-r-y',
repositories: [
{
name: 'Discord-Bot-01',
url: 'https://github.com/B-l-u-e-b-e-r-r-y/Discord-Bot-01',
files: ['discord.js', 'README.md'],
releases: [
{
version: '1.0',
releaseDate: '2021-08-20',
description: '...'
}
]
}
]
}
}, {
name: 'Foo',
github: null
}
]

// 取 releases 的 releaseDate
users.map(user =>
user.github
&& user.github.repositories
&& user.github.repositories.length > 0
&& user.github.repositories[0].releases
&& user.github.repositories[0].releases.length > 0
&& user.github.repositories[0].releases[0].releaseDate);

這樣就會很辛苦 QQ

使用方法

所幸現在 Chrome 支援 Optional Chaining,能夠讓上面落落長的程式碼只用一行搞定。

1
users.map(user => user.github?.repositories?.[0]?.releases?.[0]?.releaseDate);

運作流程如下:

  • user 如果存在 github 就繼續往下查找
    • user 如果不存在 github 就回傳 undefined
  • github 如果存在 repositories 就繼續往下查找
  • repositories 如果存在 repositories[0] 就繼續往下查找

…以此類推。

目前 Optional chaining 除了 IE 以外的瀏覽器都支援,也支援 Node.js v14.0.0 版本以上,詳細可以看瀏覽器相容性


參考資料

文章結束囉~

如果我的文章對你有幫助,可以幫我拍個手,感謝支持!