JavaScriptで「||」ORと「??」Nullishは同じではない
分かっていてもコードを書いているとハマることがある「||」と「??」の使い分け。
ちゃんと理解していれば、自分のコードではハマる率は低いかもしれないけど人が書いているコードだと、うっかりハマってしまうことがあります。
プロジェクト的に明確な使い分けをせずに一律して使われてしまうこともある倫理ORの「||」とNullish coalescing 演算子の「??」。
実は最近、すでに存在しているコードを触っていてハマってしまったので改めて違いを整理します。
「||」倫理 OR 演算子
「||」は左辺がfalseに該当する場合に右辺の値を返します。
例えば下記のように左辺がfalse判定されていればすべて右辺のhogeが変数sampleに入ります。
1 2 3 4 5 6
const sample = '' || 'hoge' const sample = 0 || 'hoge' const sample = NaN || 'hoge' const sample = false || 'hoge' const sample = null || 'hoge' const sample = undefined || 'hoge'
文字列では空文字でなかったり、数値なら0より大きい値、その他の上記の値以外でなければ左辺は適用されません。
「??」 Nullish coalescing 演算子
「??」は左辺がfalseに該当する場合に右辺の値を返す、という意味では「||」と似ていますが、厳密には違いがあります。
それは「??」はundefinedとnullののときにのみ、右辺が適用されます。
1 2 3 4 5 6
const sample = '' ?? 'hoge' // '' const sample = 0 ?? 'hoge' // 0 const sample = NaN ?? 'hoge' // NaN const sample = false ?? 'hoge' // false const sample = null ?? 'hoge' // 'hoge' const sample = undefined ?? 'hoge' // 'hoge'
「||」と「??」はどちらを使うか
「||」と「??」は意味が違うのは分かったけど、どっちを使えばいいのか。
個人的にはとりあえず「||」を使っておけば良いと思っています。
理由は「||」や「??」を使うシチュエーションは左辺が有効な値でないときに右辺の値を使いたい、という場合が多いからです。
特にハマりやすいポイントとして下記のような時です。
1
const sample = obj?.sample ?? 'hoge'
TypeScriptでobjがoptionalでsampleがstringやnumberの場合に、ハマりがち。
「??」を使うとobjが存在していなければundefinedのためhogeになりますが、sampleが空文字や0ならhogeになりません。
意図的に空文字や0を代入したいなら、もちろん「??」を使うべきですが、こういう場合って大体hogeになることが期待されているほうが多いように思います。
これは「??」を使っているから起きたことで「||」を使っていれば起きない問題です。
まとめ
最後にまとめると「||」と「??」の使い分けは下記になります。
- 「||」:falseに該当する値で右辺を適用したいとき
- 「??」:undefinedとnullの時のみ右辺を適用したいとき
使い分けを分かっていても、日々コードを読んでいる中だと見落としてしまうこともあるのでちゃんと意味を理解した上で実装に組み込まないとハマることになります。