Menu
日本語

JavaScriptのnullとundefinedの違い・判定方法・使い分け

JavaScriptのnullとundefinedは何がどう違うのか、両方をまとめて判定する書き方、そして自分のコードではどちらを使うべきかを整理します。

「何もない」を表す2つの値

多くの言語では「値がない」を表すものは1つだけですが、JavaScriptには nullundefined という2つがあります。両者は紛らわしいほど似た振る舞いをする一方で、微妙に違うせいでベテラン開発者でもつまずくことがあります。この違いをきちんと押さえておくのは、10分の投資に見合う価値があります。

ざっくり言うと、こうです。

  • undefined は、何かが欠けているときにJavaScriptが勝手に割り当てる値。
  • null は、「意図的に空にしておく」と自分で明示的に書く値。
index.js
Output
Click Run to see the output here.

パターンに気づきましたか?上で出てきた undefined は、どれも JavaScript が値を見つけられなかったケースです。一方 null は、誰かが明示的に書いたから存在するんです。

undefined が現れる場面

undefined が登場するシチュエーションはいくつか決まっていて、どれも「値が用意されていない」バリエーションです。

index.js
Output
Click Run to see the output here.

いずれのケースでも、JavaScript は値を取りに行ったものの、そこに何もなかったというだけの話です。undefined は「探したけど値がなかったよ」というエンジンからのサインだと思ってください。

もちろん自分で undefined を代入することもできます(let x = undefined; のように)。ただし、やらないほうが無難です。undefined は「JavaScript が何も見つけられなかった」というシグナルとして残しておき、自分の意思で「値がない」ことを示したいときは null を使いましょう。これが null と undefined の使い分けの基本です。

null はどこから来るのか

null は、誰かが明示的に書いたときにしか現れません。つまり、そこがポイントで、意図的に「値がない」ことを示すための目印なのです。

index.js
Output
Click Run to see the output here.

DOMのAPIではnullがよく使われます。例えばdocument.getElementById("missing")の戻り値はundefinedではなくnullです。これはブラウザが「探したけど、該当する要素はなかったよ」と明示的に伝えているからです。JSON.parse("null")も同様にnullを返します。そもそもJSONにはundefinedという概念がないんですね。

イメージとしてはこうです。undefinedは「デフォルトの不在」、nullは「意図的な不在」。

typeof の落とし穴

有名なやつです。

index.js
Output
Click Run to see the output here.

typeof null"object" を返すのは、実は1995年から残っているバグなんです。修正してしまうと既存のサイトが軒並み壊れてしまうため、そのまま放置され続けています。とはいえ null はオブジェクトでは ありませんundefined や数値、文字列、真偽値と同じくプリミティブ値です。typeof の結果が嘘をついているだけ、というわけですね。

実用面での影響としては、null の判定に typeof はまったく使えません。素直に比較演算子で調べましょう。

index.js
Output
Click Run to see the output here.

もっと多い使い方としては、両方をまとめて判定するパターン——次のセクションで見ていきましょう。

== null で両方まとめて判定する

実際のコードでは、値が null なのか undefined なのかを区別する必要はほとんどありません。使う前に「値が入っていないかどうか」を確認したいだけ、というケースが大半です。そんなときの定番は、null との緩い等価比較(==)です。

index.js
Output
Click Run to see the output here.

value == null は、値が null または undefined のときだけ true になり、それ以外(0""false など)はすべて false になります。たいていの場面ではこの挙動こそが欲しいものです。=== ではなく == を使うのが推奨される、数少ないケースのひとつですね。リンターもこれを理解していて、ちゃんと許容してくれます。

もっと明示的に書きたいなら、value === null || value === undefined と書けば同じ意味になりますし、読み手にも意図が伝わりやすいです。

Nullish 演算子:???.

nullundefined を扱いやすくするために、専用の演算子が2つ追加されました。どちらもこの2つの値を同じものとして扱い、それ以外の値はそのまま素通りさせます。

Nullish 合体演算子(?? は、左辺が null または undefined のときだけフォールバック値を返します。

index.js
Output
Click Run to see the output here.

|| と比較してみてください。|| なら 0 は falsy なので 3 に置き換わってしまいます。?? はもっと厳格で、null・undefined の2つだけに反応します。

オプショナルチェーン(?. は、チェーンの途中で nullundefined に遭遇すると、そこで評価を打ち切って undefined を返します。

index.js
Output
Click Run to see the output here.

どちらの演算子も「この値は nullish なのか?」という頻出のチェックをラクに書くために用意されています。詳しい使い方はカリキュラムの後半でじっくり扱います。

デフォルト引数が効くのは undefined のときだけ

地味ですが重要なルールがあります。関数のデフォルト引数が適用されるのは undefined が渡されたときだけで、null には発動しません。

index.js
Output
Click Run to see the output here.

null を渡すと「値を設定しないことを明示的に選んだ」と見なされ、そのまま尊重されます。null の場合もデフォルト値にフォールバックさせたいなら、関数内で ?? を使いましょう。

index.js
Output
Click Run to see the output here.

この違いは本当に多くの人がハマるポイントです。デフォルト値は「引数が渡されていない」ケースを埋めるもので、?? は「nullish な値」を埋めるもの。役割が違います。

JSON に undefined が存在しない問題

JSON には null はありますが、undefined はありません。そのため、シリアライズするときに気づかないうちにハマることがあります。

index.js
Output
Click Run to see the output here.

age フィールドがまるごと消えてしまいました。JSON.stringify は値が undefined のプロパティを捨ててしまうからです。一方、null は JSON が正式にサポートしているので残ります。オブジェクトを JSON に通して戻すと、undefined のプロパティが気づかないうちに消えてしまう——これはよくある落とし穴です。

配列の場合、undefinednull に変換されます:

index.js
Output
Click Run to see the output here.

APIのペイロードを設計するときは、「値なし」を表すフィールドには undefined ではなく null を使うのがおすすめです。こちらなら通信を経ても消えずに残ります。

null と undefined の使い分け

自分のコードで採用するなら、こんなルールが現実的です。

  • undefined は「そもそも与えられていない」を表す — 引数が渡されていない、変数が未代入、プロパティが存在しない、といったケース。自分で undefined を明示的に代入するのは避けます。
  • null は「意図的に空であることをはっきり示したい」ときに使う — ログアウト状態のユーザー、未選択のオプション、クリアされたフォーム欄など。
  • API の境界では両方を受け入れる(== null?? を使う)。ただし、自分が 返す 側は必ずどちらか一方に統一しましょう。

スタイルガイドによっては(TypeScript のガイドラインなど)null を一切使わず undefined だけで通すものもあります。これも一理あって、値が 2 種類より 1 種類の方がシンプルです。プロジェクトごとに方針を決めて、全体で揃えるのが大事です。

次回:型変換(Type Coercion)

nullundefined は、JavaScript が数値・文字列・真偽値に変換するときにそれぞれ独特の挙動を見せます。たとえば Number(null)0 なのに、Number(undefined)NaN。こうした非対称さが、実際のバグの原因になったりします。次は型変換(Type Coercion)の話です。ルール全体が見えてくると、JavaScript の「クセ」と思っていた挙動の多くが、意外とスッキリ腑に落ちるはずです。

よくある質問

JavaScriptのnullとundefinedは何が違うの?

undefined は「まだ値が入っていない」状態を表します。宣言だけした変数、渡されなかった引数、存在しないオブジェクトのプロパティなど、JavaScriptが自動的に返してくるのがこれです。一方 null は「値が無いことを明示的に示す」もので、自分で意図的に代入するもの。JavaScriptが勝手に null を返してくることはなく、必ず人間が書いた場合だけ登場します。

nullとundefinedを一度にチェックするには?

value == null と書けばOKです。ゆるい等価比較(==)では、nullundefined はお互いだけが等しいと判定されるので、x == nullnullundefined のときだけ true になります。基本は === 推奨のJavaScriptですが、この書き方だけは例外的に慣用表現として定着しています。

なぜ typeof null は 'object' になるの?

これは初期のJavaScriptから残っている有名なバグで、直すと既存のWebが壊れてしまうため放置されています。null はプリミティブなのに typeof null'object' を返します。null だけをピンポイントで判定したいときは、素直に value === null と比較するのが確実です。

自分のコードではnullとundefinedどっちを使うべき?

基本方針は、undefined は「何も渡されていない」、null は「意図的に空であることを示す」と役割を分けること。ただし最近はTypeScriptのスタイルガイドを含め、null を使わず undefined に統一する派も多いです。大事なのはプロジェクト内で方針を一つに決めて、それを貫くことです。

Coddyでコードを学ぼう

始める