5日 七月 2020

NULL合体演算子(Nullish coalescing operator) '??'

A recent addition
This is a recent addition to the language. Old browsers may need polyfills.

NULL合体演算子 ?? はリストの中から最初の “定義済み” 変数を選択するための短縮構文です。

a ?? b の結果は:

  • anull あるいは undefined でなければ a,
  • それ以外の場合は b.

したがって、x = a ?? b は以下と同等です:

x = (a !== null && a !== undefined) ? a : b;

次はより長い例です。

想像してください、ユーザがいて、性、名、ニックネーム用の変数 firstName, lastName, nickName があるとします。ユーザが何も入力しなければ、それらはすべて undefined になるかもしれません。

ユーザ名を表示します: 3つの変数のいずれか、あるいは設定されていない場合は “Anonymous” とします。

?? 演算子を使って最初に定義されたものを選択しましょう。:

let firstName = null;
let lastName = null;
let nickName = "Supercoder";

// 最初の null/undefined でない値を表示します
alert(firstName ?? lastName ?? nickName ?? "Anonymous"); // Supercoder

|| との比較

OR || 演算子は ?? と同じ方法で利用することができます。前のチャプター で説明したように、実際、上のコードでは ??|| に置き換えることができ、同じ結果を得ることができます。

重要な違いは次の通りです:

  • || は最初の の値を返します。
  • ?? は最初の 定義済み の値を返します。

これは、null/undefined0 とは別に扱いたい場合、非常に重要です。

例えば、次を考えてみましょう:

height = height ?? 100;

height が未定義であれば、100 が設定されます。

|| と比較してみましょう:

let height = 0;

alert(height || 100); // 100
alert(height ?? 100); // 0

ここでは、height || 100 は 高さゼロを nullundefined あるいは他の偽の値と同様に未定義として扱っています。そのため、結果は 100 です。

height ?? 100height がまさに null あるいは undefined の場合にのみ 100 を返します。したがって、alert は高さの値 0 を “そのまま” 表示します。

どちらの振る舞いがよいかはユースケースによります。高さゼロは有効な値の場合、?? の方が好ましいです。

優先順位

?? の順位は低めです: MDN テーブル5 です。

したがって、?? は他の多くの演算子の後で、=? の前に評価されます。

複雑な式で ?? を用いて値を選択する必要がある場合は括弧を用いることを検討してください:

let height = null;
let width = null;

// 重要: 括弧を使用します
let area = (height ?? 100) * (width ?? 50);

alert(area); // 5000

そうでない場合、括弧を省略すると *?? よりも優先度が高いため、最初に実行されます。

これば次のように動くことを意味します:

// 恐らくこれは正しくない計算でしょう
let area = height ?? (100 * width) ?? 50;

また、ここには関連する言語レベルの制限もあります。

安全上の理由により、&&|| 演算子と一緒に ?? を用いることは禁止されています。

次のコードは構文エラーになります:

let x = 1 && 2 ?? 3; // Syntax error

この制限には当然議論の余地がありますが、人々が || から ?? に切り替え始めるときに、プログラミングのミスを避ける目的で言語仕様に追加されました。

回避するには明示的に括弧を使用します:

let x = (1 && 2) ?? 3; // 動作します

alert(x); // 2

サマリ

  • Null合体演算子 ?? は一覧から “定義済み” の値を選択するための簡単な方法を提供します。

    変数にデフォルト値を代入するために使用されます:

    // height が null あるいは undefined であれば height=100 を設定します
    height = height ?? 100;
  • 演算子 ?? は優先度が低く、?= よりも少し高い程度です。

  • 明示的な括弧なしに ||&& と一緒に利用することは禁止されています。

チュートリアルマップ

コメント

コメントをする前に読んでください…
  • 自由に記事への追加や質問を投稿をしたり、それらに回答してください。
  • 数語のコードを挿入するには、<code> タグを使ってください。複数行の場合は <pre> を、10行を超える場合にはサンドボックスを使ってください(plnkr, JSBin, codepen…)。
  • 記事の中で理解できないことがあれば、詳しく説明してください。