JavaScript/論理和代入演算子
|=(Logical OR Assignment 論理和代入演算子)は、左辺の値が falsy(偽値)である場合にのみ右辺の値を左辺に代入する代入演算子です。この演算子を使用することで、変数やオブジェクトのプロパティに対するデフォルト値の設定を簡潔に行うことができます[1]。
構文
[編集]lhs ||= rhs
この演算子は次のコードと同等です:
lhs = lhs || rhs
ただし、lhs は一度だけ評価されます。
例
[編集]基本的な使用法
[編集]以下のプログラムは、論理和代入演算子の基本的な使用法を示しています。
// 基本的な使用法 let a = null; let b = undefined; let c = ""; let d = 0; let e = false; let f = "既存の値"; // falsyな値の場合に右辺が代入される a ||= "デフォルト値"; b ||= "デフォルト値"; c ||= "デフォルト値"; d ||= "デフォルト値"; e ||= "デフォルト値"; f ||= "新しい値"; console.log(a); // "デフォルト値" console.log(b); // "デフォルト値" console.log(c); // "デフォルト値" console.log(d); // "デフォルト値" console.log(e); // "デフォルト値" console.log(f); // "既存の値" (変更されない)
このプログラムでは、論理和代入演算子(|=)を使用して、変数が falsy である場合にデフォルト値を代入しています。変数 a、b、c、d、e は falsy な値なので、デフォルト値が代入されますが、変数 f は truthy な値なので変更されません。
オブジェクトのプロパティに対する使用
[編集]以下のプログラムは、オブジェクトのプロパティに対する論理和代入演算子の使用例を示しています。
// オブジェクトのプロパティに対する使用 const user = { name: "Alice", settings: { theme: "", notifications: false, fontSize: 0 } }; // 既存のプロパティに対する使用 user.settings.theme ||= "ダークモード"; user.settings.notifications ||= true; user.settings.fontSize ||= 16; user.settings.language ||= "ja"; // プロパティが存在しない場合も新規作成される console.log(user.settings.theme); // "ダークモード" console.log(user.settings.notifications); // true console.log(user.settings.fontSize); // 16 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); // "ライトモード"
このプログラムでは、オブジェクトのプロパティに対して論理和代入演算子を使用しています。user.settings.theme、user.settings.notifications、user.settings.fontSize はそれぞれ falsy な値なので、デフォルト値が代入されます。また、存在しないプロパティ user.settings.language に対しても使用でき、プロパティが新規作成されます。
なお、オプショナルチェイニングと組み合わせる場合は注意が必要であり、単純に obj?.prop ||= value とすることはできません。代わりに、親オブジェクトを先に初期化する必要があります。
関数内での使用
[編集]以下のプログラムは、関数内での論理和代入演算子の使用例を示しています。
// 関数内での使用 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, language: "" }; console.log(initializeUserConfig(userConfig1)); // { theme: "カスタムテーマ", fontSize: 14, showNotifications: true, language: "en" } console.log(initializeUserConfig(userConfig2)); // { showNotifications: true, language: "en", theme: "デフォルトテーマ", fontSize: 16 }
このプログラムでは、関数内で論理和代入演算子を使用して、オブジェクトの欠けているプロパティや falsy な値を持つプロパティにデフォルト値を設定しています。特に注目すべき点として、userConfig2 の showNotifications は false という値を持っていますが、これは falsy なので true に置き換えられています。これが 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 = "値"; // 論理OR代入演算子 (||=) a1 ||= "デフォルト"; b1 ||= "デフォルト"; c1 ||= "デフォルト"; // Nullish 合体代入演算子 (??=) a2 ??= "デフォルト"; b2 ??= "デフォルト"; c2 ??= "デフォルト"; // 論理AND代入演算子 (&&=) a3 &&= "デフォルト"; b3 &&= "デフォルト"; c3 &&= "デフォルト"; console.log("論理OR代入 (||=):", a1, b1, c1); // "デフォルト", "デフォルト", "値" console.log("Nullish 合体代入 (??=):", a2, b2, c2); // "デフォルト", 0, "値" console.log("論理AND代入 (&&=):", a3, b3, c3); // null, 0, "デフォルト"
このプログラムでは、3つの論理代入演算子の動作の違いを比較しています:
|=(論理OR代入)は falsy 値(0、""、false、null、undefinedなど)の場合に代入します??=(Nullish 合体代入)はnullまたはundefinedの場合のみ代入します&&=(論理AND代入)は truthy 値の場合のみ代入します
注意点
[編集]- 短絡評価: 論理和代入演算子は短絡評価を行います。左辺が truthy な値である場合、右辺の評価は行われません。
- 左辺の評価回数: 通常の
lhs = lhs || rhsと異なり、lhs ||= rhsでは左辺の式は一度だけ評価されます。 - プロパティアクセス: 存在しないオブジェクトのプロパティにアクセスしようとするとエラーになるため、オプショナルチェイニングとの組み合わせには注意が必要です。
- イミュータブルな値:
constで宣言された変数や、Object.freeze()で凍結されたオブジェクトのプロパティなど、再代入できない値に対して使用するとエラーになります。 - falsy値への注意: 論理和代入演算子は
0やfalseなどの有効な値も falsy として扱うため、これらの値を保持したい場合は Nullish 合体代入演算子(??=)の方が適切な場合があります。