JavaScript Tips | 基本・共通ユーティリティ:安全処理 – null 合体代入

JavaScript JavaScript
スポンサーリンク

「null 合体代入」とは何をしてくれる構文か

「null 合体代入」は、
「その変数が null または undefined のときだけ、デフォルト値を代入する」
ということを一発で書ける構文です。

JavaScript では、これを ??= という演算子で書きます。

value ??= defaultValue;
JavaScript

意味としては、こうです。

if (value === null || value === undefined) {
  value = defaultValue;
}
JavaScript

これを一行で、しかも意図がはっきりした形で書けるのが「null 合体代入」です。


まずは基本:null 合体演算子 ?? との関係

?? と ??= の違いを押さえる

?? は「式」として使う演算子です。

const pageSize = input.pageSize ?? 20;
JavaScript

これは「input.pageSizenull / undefined なら 20、それ以外ならそのまま」という意味です。

一方、??= は「代入演算子」です。

pageSize ??= 20;
JavaScript

これは「pageSizenull / undefined のときだけ 20 を代入する」という意味です。

つまり、

x = x ?? defaultValue;
JavaScript

を短く書いたのが

x ??= defaultValue;
JavaScript

だと思ってもらえば OK です。


null 合体代入の基本的な挙動

どんなときに代入されるのか

いくつかパターンを見てみましょう。

let value;

// 1. undefined のとき
value = undefined;
value ??= 10;
console.log(value); // 10

// 2. null のとき
value = null;
value ??= 10;
console.log(value); // 10

// 3. 0 のとき
value = 0;
value ??= 10;
console.log(value); // 0(そのまま) 

// 4. 空文字のとき
value = "";
value ??= "default";
console.log(value); // ""(そのまま)

// 5. false のとき
value = false;
value ??= true;
console.log(value); // false(そのまま)
JavaScript

ここで一番大事なポイントは、
0""false は“ちゃんとした値”として扱われ、上書きされない」ということです。

||=(論理和代入)と混同すると危険なので、違いを意識しておきましょう。


なぜ業務で「null 合体代入」が効いてくるのか

業務コードでは、「設定値」「オプション」「外部入力」がとにかく多いです。

例えば、こんな状況を考えてみます。

let options = {
  pageSize: undefined,
  theme: "dark",
};
JavaScript

ここで、「pageSize が指定されていなければ 20 を入れたい」というとき、
null 合体代入を使うとこう書けます。

options.pageSize ??= 20;
console.log(options);
// { pageSize: 20, theme: "dark" }
JavaScript

もし pageSize に 0 が入っていたら、それは「意図的に 0 を指定した」とみなして、そのまま残ります。

options.pageSize = 0;
options.pageSize ??= 20;
console.log(options.pageSize); // 0 のまま
JavaScript

null / undefined のときだけデフォルトを入れる」
という業務でよくある要件を、短く・安全に書けるのが null 合体代入です。


よくある「ダメな書き方」との比較

||= を使ってしまうと何が起きるか

似た構文に ||=(論理和代入)があります。

value ||= 10;
JavaScript

これは「value が falsy(0, “”, false, null, undefined など)のときに 10 を代入する」という意味です。

業務でやりがちなのが、これを「デフォルト代入」として使ってしまうことです。

let pageSize = 0;
pageSize ||= 20;
console.log(pageSize); // 20(0 が消える)
JavaScript

「0 も有効な値」として扱いたい場面では、これはバグになります。

同じことを null 合体代入で書くとこうなります。

let pageSize = 0;
pageSize ??= 20;
console.log(pageSize); // 0(意図通り)
JavaScript

ここが null 合体代入を“安全処理”として使う最大のポイントです。
「0 や空文字を潰さない」「本当に“値がない”ときだけデフォルトを入れる」ことができます。


ユーティリティとしての null 合体代入の使い方

設定オブジェクトの初期化

設定オブジェクトに対して、「足りないところだけ埋める」処理はよく出てきます。

function initOptions(options) {
  options.pageSize ??= 20;
  options.theme ??= "light";
  options.lang ??= "ja";
  return options;
}
JavaScript

使い方はこうです。

const userOptions = { theme: "dark" };

const finalOptions = initOptions(userOptions);
console.log(finalOptions);
// { theme: "dark", pageSize: 20, lang: "ja" }
JavaScript

ここでのポイントは、

「ユーザーが指定していない項目だけデフォルトを入れる」
null / undefined のときだけ埋める」

というルールが、??= でとても素直に表現できていることです。


「undefined 防止代入」との関係

以前話した「undefined 防止代入」と、null 合体代入はかなり近い発想です。

undefined 防止代入
undefined のときだけ上書きしない/上書きする」

null 合体代入
null / undefined のときだけデフォルトを代入する」

どちらも、「よく分からない値で、ちゃんとした値を壊したくない」という目的を持っています。

違いは、「null をどう扱うか」です。

  • undefined だけ特別扱いしたいなら、自前の条件やユーティリティ関数を使う
  • null も「値がない」とみなしたいなら、??=` を使う

という整理をしておくと、設計がぶれません。


実務での具体的な利用イメージ

API レスポンスの補完

API からのレスポンスに「オプション項目」がある場合、
「なければデフォルトを入れてから使う」というのはよくあるパターンです。

function normalizeUser(raw) {
  raw.name ??= "名無し";
  raw.role ??= "user";
  raw.active ??= true;
  return raw;
}
JavaScript

これで、「name が null / undefined のユーザーでも、アプリ内部では必ず文字列として扱える」状態になります。

ローカルストレージからの復元

ローカルストレージから設定を復元するときも、null 合体代入は相性がいいです。

function loadSettings() {
  const json = localStorage.getItem("settings");
  const settings = json ? JSON.parse(json) : {};

  settings.theme ??= "light";
  settings.lang ??= "ja";

  return settings;
}
JavaScript

「保存されていない項目だけデフォルトを入れる」という処理が、かなり読みやすく書けます。


小さな練習で感覚をつかむ

次のような値を用意して、自分で ??=||= の挙動を比べてみてください。

let v;

// それぞれについて v ??= 100 と v ||= 100 を試す
v = undefined;
v = null;
v = 0;
v = "";
v = false;
v = 123;
JavaScript

「どのときに上書きされるか」「どのときに元の値が残るか」を自分の目で確認すると、
「null 合体代入は“本当に値がないときだけ埋める”ためのもの」
という感覚がしっかり入ってきます。

そこまで理解できたら、あとはあなたのプロジェクトの中で、

「ここ、null / undefined のときだけデフォルトを入れたいんだよな」

という場所に、少しずつ ??= を差し込んでいけば、
設定やオプションまわりのバグがかなり減っていきます。

タイトルとURLをコピーしました