JavaScript/??=
??=
(Nullish Coalescing Assignment
Null 合体代入演算子、または Nullish 合体代入演算子)は、左辺の値が null
または undefined
の場合にのみ右辺の値を左辺に代入する代入演算子です。この演算子を使用することで、変数やオブジェクトのプロパティに対するデフォルト値の設定を簡潔に行うことができます[1]。
構文
lhs ??= rhs
この演算子は次のコードと同等です:
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
の場合にのみデフォルト値を代入しています。変数 a
と b
は null
と undefined
なので、デフォルト値が代入されますが、変数 c
、d
、e
はそれ以外の値なので変更されません。
オブジェクトのプロパティに対する使用
以下のプログラムは、オブジェクトのプロパティに対する 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.theme
と user.settings.notifications
はそれぞれ null
と undefined
なので、デフォルト値が代入されます。また、存在しないプロパティ 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つの論理代入演算子の動作の違いを比較しています:
注意点
- 短絡評価: Nullish 合体代入演算子は短絡評価を行います。左辺が
null
またはundefined
でない場合、右辺の評価は行われません。 - 左辺の評価回数: 通常の
lhs = lhs ?? rhs
と異なり、lhs ??= rhs
では左辺の式は一度だけ評価されます。 - プロパティアクセス: 存在しないオブジェクトのプロパティにアクセスしようとするとエラーになるため、オプショナルチェイニングとの組み合わせには注意が必要です。
- イミュータブルな値:
const
で宣言された変数や、Object.freeze()
で凍結されたオブジェクトのプロパティなど、再代入できない値に対して使用するとエラーになります。 - 関数引数: 関数の引数にデフォルト値を設定する場合は、Nullish 合体代入演算子よりもパラメータのデフォルト値構文(
function func(param = defaultValue) {...}
)を使用する方が適切な場合が多いです。