[PR] 本記事にはプロモーションが含まれています。

【JavaScript】??(Null合体演算子)と三項演算子・|| の違い|0や空文字を消さないデフォルト値の書き方

JavaScript

JavaScriptで「値がなければデフォルト値を使う」ような書き方をするとき、??(Null合体演算子)、||(論理和)、? :(三項演算子)のどれを使うかで迷うことがあります。どれも似た結果になることが多いのですが、0 や空文字の扱いが違うため、選び方を間違えると「0を設定したのにデフォルト値になる」といった不具合になります。

この記事では、3つの違いと使い分けを、実際に動くコードで確かめます。

3つの演算子の違い

  • a ?? b:a が null か undefined のときだけ b になる。それ以外は a のまま
  • a || b:a が Falsy(後で説明)なら b になる。0 や空文字も b に置き換わる
  • 条件 ? x : y:条件が成り立つなら x、成り立たなければ y になる。条件は自由に書ける

?? と || は「デフォルト値を入れる」ための演算子、三項演算子は「条件で値を切り替える」ための演算子と考えると整理しやすくなります。?? はES2020で追加された、比較的新しい演算子です。

Falsy(偽とみなされる値)とは

JavaScriptでは、if文や || などで「偽」として扱われる値を Falsy と呼びます。主な Falsy な値は次のとおりです。

値意味
false真偽値の偽
0、-0数値の0
0nBigInt(大きな整数の型)の0
""空文字
null「値がない」を表す値
undefined「まだ値が入っていない」を表す値
NaN数値ではないことを表す値

?? が反応するのは、このうち null と undefined の2つだけです。C言語でも 0 は偽として扱われますが、JavaScriptでは空文字や NaN も偽になるのが違うところです。

0を設定したのにデフォルト値になる例

「表示する件数」をユーザーが設定できて、設定がなければ10件にする場合を考えます。ユーザーが、わざと 0 を設定したとします。

JavaScript
const userCount = 0; // ユーザーがわざと 0 を設定した

console.log(userCount ?? 10);            // 0 (0 は null でも undefined でもないので、そのまま)
console.log(userCount || 10);            // 10(0 は Falsy なので、10 に置き換わる)
console.log(userCount ? userCount : 10); // 10(|| と同じ結果)

|| や「userCount ? userCount : 10」の書き方だと、意図して設定した 0 が 10 に置き換わってしまいます。?? なら、未設定(null や undefined)のときだけ 10 になり、0 はそのまま残ります。

いろいろな値で比べると、次のようになります(コメントの結果は、見やすいように整えています。コンソールでは空文字が何も表示されないなど、見た目が少し違います)。

JavaScript
const values = [null, undefined, 0, '', false, NaN, 5, 'abc'];

for (const v of values) {
  console.log(v, '→ ??:', v ?? 'デフォルト', '/ ||:', v || 'デフォルト');
}

// null      → ??: デフォルト / ||: デフォルト
// undefined → ??: デフォルト / ||: デフォルト
// 0         → ??: 0          / ||: デフォルト
// ''        → ??: ''         / ||: デフォルト
// false     → ??: false      / ||: デフォルト
// NaN       → ??: NaN        / ||: デフォルト
// 5         → ??: 5          / ||: 5
// 'abc'     → ??: 'abc'      / ||: 'abc'

結果が分かれるのは、0、空文字、false、NaN のときです。これらを「正しい値」として受け付けたいなら ??、「値がないのと同じ」として扱いたいなら || を使います。たとえば、入力欄が空なら「名無し」と表示したいときは、空文字も置き換えたいので || が合っています。

三項演算子で書くとどうなる?

?? と同じ動きは、三項演算子でも書けます。?? がなかったころは、このように書いていました。

JavaScript
const userCount = 0;

// ?? と同じ動きを三項演算子で書いた形
const count1 = userCount !== null && userCount !== undefined ? userCount : 10;

// ?? を使うと、これだけで済む
const count2 = userCount ?? 10;

console.log(count1, count2); // 0 0

結果は同じですが、?? のほうが短く、「値がなければ 10」という意図が読み取りやすくなります。デフォルト値を入れるだけなら、?? を使うのがおすすめです。

三項演算子が向いている場面

三項演算子は、null かどうかに限らず、どんな条件でも書けます。数値の大きさや文字列の中身で値を切り替えるときは、三項演算子を使います。

JavaScript
const score = 85;
const result = score >= 80 ? '合格' : '不合格';
console.log(result); // 合格

ただし、三項演算子を何重にも重ねると読みにくくなります。条件が3つ以上になるときは、if文で書いたほうが分かりやすいことが多いです。

JavaScript
// 重ねすぎた例(読みにくい)
const grade = score >= 90 ? 'A' : score >= 80 ? 'B' : score >= 70 ? 'C' : 'D';

?? と一緒によく使う書き方

?.(オプショナルチェーン)と組み合わせる

オブジェクトの奥の値を読むとき、途中が null や undefined だとエラーになります。?. を使うと、途中に値がなければエラーにせず undefined を返すので、?? と組み合わせてデフォルト値を入れられます。

JavaScript
const settings = {}; // display の設定がまだない

// settings.display.count と書くと、display が undefined なのでエラーになる
const count = settings.display?.count ?? 10;
console.log(count); // 10

??=(Null合体代入)

「変数が null か undefined のときだけ、値を入れる」ときは ??= も使えます(ES2021で追加)。

JavaScript
const options = { count: 0 };

options.count ??= 10; // 0 なので変わらない
options.title ??= '一覧'; // まだないので '一覧' が入る

console.log(options); // { count: 0, title: '一覧' }

注意:|| や && と混ぜるときはカッコが必要

?? を || や && とカッコなしで並べると、文法エラーになります。どちらを先に計算するか、カッコではっきり書く必要があります。

JavaScript
const a = null;
const b = 0;

// const x = a || b ?? 10;   // SyntaxError(カッコがないとエラー)
const x = (a || b) ?? 10;    // OK
console.log(x); // 0

どれを使うかの目安

  • 値がないときだけデフォルト値にしたい(0 や空文字も正しい値として残したい)→ ??
  • 空文字や 0 も「値がない」として扱いたい → ||
  • 大きさや中身など、条件で値を切り替えたい → 三項演算子(条件が多いときは if文)

迷ったときは、「0 や空文字が来たらどうしたいか」を考えると決めやすくなります。

まとめ

  • ?? は null と undefined のときだけ右側の値になる。0 や空文字はそのまま残る
  • || は Falsy な値をすべて右側の値に置き換える
  • 三項演算子は、どんな条件でも値を切り替えられる
  • ?. や ??= と組み合わせると便利。|| や && と混ぜるときはカッコを付ける

この記事のコードは、ブラウザのコンソールやCodePenに貼ればすぐに試せます。あわせて、「文字列の ‘ と ” と ` の違い」や「filterメソッドの書き方」も参考にしてみてください。

ほかの開発・プログラミングの記事は、開発・プログラミングメモの目次から、テーマ別に探せます。

このブログは、にほんブログ村と人気ブログランキングに参加しています。記事が役に立ったら、下のランキングのバナーのどれかを押して応援してもらえると励みになります。

ブログランキング・にほんブログ村へにほんブログ村

サーバー構築・運用ランキング プログラムランキング

JavaScript
watasoftdevをフォローする

コメント