JS之路 Day24 - nullish coalescing operator (空值合併運算子)
前言
之前講的是常用的邏輯運算子,而有一個比較特別的,寫法是兩個問號。
之前看不太懂,趁著今天研究出來順便寫自己的理解,接下來就直接開始。
??
根據 MDN 的解釋,當左邊的值是null或是undefined時,會回傳右邊的值,假如不是null或是undefined就會回傳左邊的值。
還記得前天講的||嗎?
||是碰到第一個真值就回傳。
而當一個值,如果它不是null也不是undefined,那它就會是defined,意思是一個已經定義的值。
所以||跟??來做比較的話:
??會回傳第一個已經定義的值||會回傳第一個遇到的真值(true)
來試試看 =>
左邊是null時,會回傳右邊的值,左邊不是null或是undefined,就會直接回傳左邊的值。
1 | console.log(null ?? 100); // 100 |
MDN 只有說左右兩側,測試看看假如兩組值以上的狀況。
1 | console.log(null ?? null ?? 100 ?? 50); // 100 |
也是一樣效果,會回傳第一個已經定義的值,讓我想到一個問題,如果全部都沒有定義的值呢?
1 | console.log(null ?? undefined); // undefined |
結果來看會回傳最後一個沒定義的值。
還有就是 MDN 裡面有提到說,不能跟||及&&共用。
1 | console.log(null ?? "1" || null); // SyntaxError |
把目前的資訊整理一下。
??主要用來邏輯判斷定義的值及未定義的值。
要是遇到第一個已經定義的值就直接回傳,否則就一直向右尋找,要是都沒有的話,就回傳最後一個未定義的值,然後不能跟其他邏輯運算子共用。
使用情境
可以用在需要提供默認值的場合。
比如說,如果fruit的值不是不是null也不是undefined,就會顯示fruit的值,不然就顯示字串水果。
在這裡字串水果就是fruit的默認值。
1 | let fruit = "蘋果"; |
1 | let fruit = undefined; |
假如今天有一家水果店,開放標一顆蘋果,就可以利用??來判斷是誰搶到了,不買的人就用null表示,會按照順序問下去。
1 | let first = null; |
有人可能會問說,那幹嘛不用||就好?
依據碰到第一個真值就回傳的特性,在上面的例子使用||結果也會完全一模一樣。
1 | let first = null; |
這邊要先從發展的角度來說。
過去的||,現在的??
??是很後期大約在ES11才出現的新語法,代表著是先有||,才有??的誕生。
而會有這種狀況的產生,我的理解是因為有些||沒辦法顧及的狀況,所以才需要有一個跟||很像但又不完全一樣的語法。
而這個答案其實前面就有暗示了。
||會回傳真值,而??會回傳已定義的值。
這邊代表一件事情,那就是||只能判斷真值跟假值,也就是說,全部的假值都不會被回傳。
不論是0,“”,NaN,null,undefined,全部都不會被回傳。||沒有辦法區分它們。
這樣會造成很多麻煩的點在於,假如我今天想要的值就是0,那麼使用||將會沒辦法達到我想要預期的結果。
1 | let scope = 0; |
我的變數值想設定成0,但是會發現說使用||會沒有辦法顯示出來,會直接跳到默認值,因為對於||來說,0是假值,不會回傳。
但如果使用??就不會發生這種問題,它會先判斷是不是有定義的值,如果不是非定義的值(null,undefined),那就會是有效值,就不會被替換成默認值了。