JavaScript/??=

カテゴリ:Book:JavaScript#%3F%3F=%20

??=Nullish Coalescing Assignment Null 合体代入演算子、または Nullish 合体代入演算子)は、左辺の値が null または undefined の場合にのみ右辺の値を左辺に代入する代入演算子です。この演算子を使用することで、変数やオブジェクトのプロパティに対するデフォルト値の設定を簡潔に行うことができます[1]

構文

lhs ??= rhs
  • lhs: 代入先の変数やプロパティや配列要素参照などの左辺値式
  • rhs: 左辺が null または undefined の場合に評価され代入される右辺の式

この演算子は次のコードと同等です:

lhs = lhs ?? rhs

ただし、lhs は一度だけ評価されます。

基本的な使用法

以下のプログラムは、Nullish 合体代入演算子の基本的な使用法を示しています。

// 基本的な使用法
let a = null;
let b = undefined;
let c = "既存の値";
let d = 0;
let e = false;

// nullとundefinedの場合のみ右辺が代入される
a ??= "デフォルト値";
b ??= "デフォルト値";
c ??= "新しい値";
d ??= 42;
e ??= true;

console.log(a); // "デフォルト値"
console.log(b); // "デフォルト値"
console.log(c); // "既存の値" (変更されない)
console.log(d); // 0 (変更されない)
console.log(e); // false (変更されない)

このプログラムでは、Nullish 合体代入演算子(??=)を使用して、変数が null または undefined の場合にのみデフォルト値を代入しています。変数 abnullundefined なので、デフォルト値が代入されますが、変数 cde はそれ以外の値なので変更されません。

オブジェクトのプロパティに対する使用

以下のプログラムは、オブジェクトのプロパティに対する Nullish 合体代入演算子の使用例を示しています。

// オブジェクトのプロパティに対する使用
const user = {
  name: "Alice",
  settings: {
    theme: null,
    notifications: undefined
  }
};

// 既存のプロパティに対する使用
user.settings.theme ??= "ダークモード";
user.settings.notifications ??= true;
user.settings.language ??= "ja"; // プロパティが存在しない場合も新規作成される

console.log(user.settings.theme); // "ダークモード"
console.log(user.settings.notifications); // true
console.log(user.settings.language); // "ja"

// オプショナルチェイニングとの組み合わせ
const userWithoutSettings = {
  name: "Bob"
};

// 以下はエラーになる(undefined.theme に代入しようとしている)
// userWithoutSettings.settings.theme ??= "ライトモード";

// オプショナルチェイニングを使用して安全に代入する方法
userWithoutSettings.settings = userWithoutSettings.settings ?? {};
userWithoutSettings.settings.theme ??= "ライトモード";

console.log(userWithoutSettings.settings.theme); // "ライトモード"

このプログラムでは、オブジェクトのプロパティに対して Nullish 合体代入演算子を使用しています。user.settings.themeuser.settings.notifications はそれぞれ nullundefined なので、デフォルト値が代入されます。また、存在しないプロパティ user.settings.language に対しても使用でき、プロパティが新規作成されます。

なお、オプショナルチェイニングと組み合わせる場合は注意が必要であり、単純に obj?.prop ??= value とすることはできません。代わりに、親オブジェクトを先に初期化する必要があります。

関数内での使用

以下のプログラムは、関数内での Nullish 合体代入演算子の使用例を示しています。

// 関数内での使用
function initializeUserConfig(config) {
  // デフォルト設定を適用
  config.theme ??= "デフォルトテーマ";
  config.fontSize ??= 16;
  config.showNotifications ??= true;
  config.language ??= "en";
  
  return config;
}

const userConfig1 = {
  theme: "カスタムテーマ",
  fontSize: 14
};

const userConfig2 = {
  showNotifications: false
};

console.log(initializeUserConfig(userConfig1));
// { theme: "カスタムテーマ", fontSize: 14, showNotifications: true, language: "en" }

console.log(initializeUserConfig(userConfig2));
// { showNotifications: false, theme: "デフォルトテーマ", fontSize: 16, language: "en" }

このプログラムでは、関数内で Nullish 合体代入演算子を使用して、オブジェクトの欠けているプロパティにデフォルト値を設定しています。この方法は、オブジェクトの一部のプロパティだけを指定して残りをデフォルト値にしたい場合に便利です。

論理代入演算子との比較

以下のプログラムは、Nullish 合体代入演算子と他の論理代入演算子(||=&&=)の違いを示しています。

// 論理代入演算子の比較
let a1 = null;
let a2 = null;
let a3 = null;

let b1 = 0;
let b2 = 0;
let b3 = 0;

let c1 = "値";
let c2 = "値";
let c3 = "値";

// Nullish 合体代入演算子 (??=)
a1 ??= "デフォルト";
b1 ??= "デフォルト";
c1 ??= "デフォルト";

// 論理OR代入演算子 (||=)
a2 ||= "デフォルト";
b2 ||= "デフォルト";
c2 ||= "デフォルト";

// 論理AND代入演算子 (&&=)
a3 &&= "デフォルト";
b3 &&= "デフォルト";
c3 &&= "デフォルト";

console.log("Nullish 合体代入 (??=):", a1, b1, c1);
// "デフォルト", 0, "値"

console.log("論理OR代入 (||=):", a2, b2, c2);
// "デフォルト", "デフォルト", "値"

console.log("論理AND代入 (&&=):", a3, b3, c3);
// null, 0, "デフォルト"

このプログラムでは、3つの論理代入演算子の動作の違いを比較しています:

  1. ??=(Nullish 合体代入)は null または undefined の場合のみ代入します
  2. ||=(論理OR代入)は falsy 値(0""falsenullundefined など)の場合に代入します
  3. &&=(論理AND代入)は truthy 値の場合のみ代入します

注意点

  • 短絡評価: Nullish 合体代入演算子は短絡評価を行います。左辺が null または undefined でない場合、右辺の評価は行われません。
  • 左辺の評価回数: 通常の lhs = lhs ?? rhs と異なり、lhs ??= rhs では左辺の式は一度だけ評価されます。
  • プロパティアクセス: 存在しないオブジェクトのプロパティにアクセスしようとするとエラーになるため、オプショナルチェイニングとの組み合わせには注意が必要です。
  • イミュータブルな値: const で宣言された変数や、Object.freeze() で凍結されたオブジェクトのプロパティなど、再代入できない値に対して使用するとエラーになります。
  • 関数引数: 関数の引数にデフォルト値を設定する場合は、Nullish 合体代入演算子よりもパラメータのデフォルト値構文(function func(param = defaultValue) {...})を使用する方が適切な場合が多いです。

脚註

  1. Nullish 合体代入演算子は、Nullish 合体演算子(??)と代入演算子(=)を組み合わせた論理代入演算子の一種です。

外部リンク

カテゴリ:Book:JavaScript#%3F%3F=%20 カテゴリ:JavaScript
カテゴリ:Book:JavaScript カテゴリ:JavaScript カテゴリ:Pages using the JsonConfig extension