一、鏈判斷運算符(?. 運算符)
實際開發中,如果要讀取對象內部的某個屬性,往往需要先判斷一下該對象是否存在。
比如,要讀取 user.firstName
,安全的寫法應該是下面這樣的:
const firstName = (user && user.firstName) || 'default'
這樣的層層判斷非常麻煩,因此 ES2020 引入了“鏈判斷運算符”(optional chaining operator)?. 來
簡化上面的寫法
const firstName = user?.firstName || 'default'
上面代碼使用了
?.
運算符,直接在鏈式調用的時候判斷,左側的對象是否爲null
或undefined
。如果是的,就不再往下運算,而是返回undefined
。
使用這個運算符,有幾個注意點:
(1)短路機制
a?.[++x]
// 等同於
a == null ? undefined : a[++x]
上面代碼中,如果 a
是 undefined
或 null
,那麼 x
不會進行遞增運算。也就是說,鏈判斷運算符一旦爲真,右側的表達式就不再求值。
(2)括號的影響
(a?.b).c
// 等價於
(a == null ? undefined : a.b).c
上面代碼中,?.
對圓括號外部沒有影響,不管 a
對象是否存在,圓括號後面的 .c
總是會執行。
一般來說,使用 ?.
運算符的場合,不應該使用圓括號。
(3)右側不得爲十進制數值
爲了保證兼容以前的代碼,允許 foo ?. 3 : 0
被解析成 foo ? .3 : 0
,因此規定如果 ?.
後面緊跟一個十進制數字,那麼 ?.
不再被看成是一個完整的運算符,而會按照三元運算符進行處理,也就是說,那個小數點會歸屬於後面的十進制數字,形成一個小數。
二、Null 判斷運算符
讀取對象屬性的時候,如果某個屬性的值是 null
或 undefined
,有時候需要爲它們指定默認值。常見做法是通過 ||
運算符指定默認值。
const text = data.text || 'Hello, world!'
上面的代碼都通過 ||
運算符指定默認值,但是這樣寫可能和預期的結果不一致。
開發者的原意是,只要屬性的值爲 null
或 undefined
,默認值就會生效,但是屬性的值如果爲空字符串或 false
或 0
,默認值也會生效。
爲了避免這種情況,ES2020 引入了一個新的 Null 判斷運算符??
。它的行爲類似 ||
,但是隻有運算符左側的值爲 null
或 undefined
時,纔會返回右側的值。
const text = data.text ?? 'Hello, world!'
上面代碼中,默認值只有在屬性值爲 null
或 undefined
時,纔會生效。
這個運算符的一個目的,就是跟鏈判斷運算符 ?.
配合使用,爲 null
或 undefined
的值設置默認值。
const animationDuration = settings?.animationDuration ?? 300
上面代碼中,settings
如果是 null
或 undefined
,就會返回默認值300。
以上