16.

JavaScriptでundefinedを判定する方法|===・typeof・nullとの違い

編集

JavaScriptで値がundefinedかどうかを正しく判定するには、変数が宣言済みであることが確実なら x === undefined を、未宣言の可能性があるなら typeof x === "undefined" を使います。型変換を伴う ==undefined == nulltrue になるため、厳密な判定には === を選ぶのが原則です。

この記事の要点
  • undefined の判定には、型変換のない ===(厳密等価)を使うのが原則です。
  • x === undefined は、変数 x宣言済みであれば安全かつ明快に判定できます。
  • typeof x === "undefined" は、未宣言の変数に対してもエラーにならず判定できます。
  • x == undefined==)は undefinednull を区別しません(どちらも true)。
  • オプショナルチェーン ?. やNull合体演算子 ?? を併用すると、安全に値を取り出して既定値を補えます。

===== の違い(undefined判定では === 推奨)

JavaScriptには等価比較の演算子が2種類あります。==(等価/緩い比較)は両辺の型が異なる場合に型変換を行ってから比較します。一方、===(厳密等価)は型変換を行わず、型と値の両方が一致したときだけ true を返します。

undefined の判定では、意図しない型変換を避けるために === を使うのが安全です。次の例を見てください。

let x;  // 宣言のみ。値は undefined

console.log(x === undefined);  // true

console.log(x == undefined);   // true

console.log(x == null);       // true ← null とも一致してしまう

console.log(x === null);      // false ← undefined と null を区別

このように、=== を使えば undefinednull を明確に区別できます。「undefined だけを判定したい」のか「undefined または null のどちらでもよい」のかを意識して選びましょう。

undefined == nulltrue になる挙動

== による比較では、JavaScriptの仕様上 nullundefined は互いに等しいものとして扱われます。そのため、次のすべてが true になります。

console.log(undefined == null);      // true

console.log(null == undefined);      // true

console.log(undefined === null);     // false

この挙動を逆に利用して、「値が null または undefined のどちらかであること」を一度にチェックするイディオムもよく使われます。意図して使う分には便利な書き方です。

function isNullish(v) {

  return v == null;  // v が null または undefined なら true

}

ただし、undefined だけを厳密に判定したい場面で == を使うと、null まで巻き込んでしまうため注意が必要です。

typeof x === "undefined" が安全な理由

typeof 演算子は、オペランドの型を表す文字列を返します。値が undefined のとき、typeof は文字列 "undefined" を返します。最大の特長は、未宣言(一度も varletconst で定義されていない)の変数に対してもエラーを投げない点です。

// notDeclared はどこにも宣言されていない変数

console.log(typeof notDeclared === "undefined");  // true(エラーにならない)

 

console.log(notDeclared === undefined);  // ReferenceError が発生

このように、notDeclared === undefined のように直接比較すると、変数自体が存在しないため ReferenceError になります。これに対し typeof notDeclared は安全に "undefined" を返すため、その変数が定義されているか分からない場合の判定に向いています。

なお、letconst で宣言された変数を「初期化前(TDZ=Temporal Dead Zone)」に typeof で参照した場合は、未宣言とは異なり ReferenceError になります。typeof が安全なのは「一度も宣言されていない名前」に対してであり、宣言済みだが初期化前の変数までエラーを防げるわけではない点に注意してください。

x === undefined との使い分け

では typeof x === "undefined"x === undefined はどう使い分ければよいのでしょうか。判断基準はシンプルで、その変数(や引数・プロパティ)が確実に宣言済みかどうかです。

function greet(name) {

  // 引数 name は宣言済みなので === で十分

  if (name === undefined) {

    name = "ゲスト";

  }

  return "こんにちは、" + name + "さん";

}

  • 宣言済みが確実(関数の引数、宣言済みローカル変数、存在するオブジェクトのプロパティなど)→ x === undefined が簡潔で読みやすい。
  • 宣言されているか不明(グローバルに後から定義される値、ライブラリ由来の変数の有無チェックなど)→ typeof x === "undefined" が安全。

オブジェクトのプロパティについては、obj.prop === undefined は「存在しないプロパティ」も「値が undefined のプロパティ」も同じく true になります。両者を区別したい場合は "prop" in objObject.hasOwn(obj, "prop") を使います。

オプショナルチェーン ?. やNull合体演算子 ?? との関係

近年のJavaScriptでは、undefined(や null)を安全に扱うための演算子が追加されています。判定そのものを書かずに済ませられる場面も多くあります。

オプショナルチェーン ?. は、参照先が null または undefined のとき、エラーを出さずに評価結果を undefined にします。

const user = { profile: null };

console.log(user.profile?.name);  // undefined(エラーにならない)

Null合体演算子 ?? は、左辺が null または undefined のときだけ右辺(既定値)を返します。|| と異なり、0""(空文字)や false を「値あり」として扱える点が重要です。

const count = 0;

console.log(count ?? 10);  // 0(0 は残る)

console.log(count || 10);  // 10(0 が falsy 扱いで消える)

 

const name = user.profile?.name ?? "名無し";  // 安全に取り出し+既定値

?.?? はいずれも nullundefined の両方を対象とします(=「Nullish」)。undefined だけを区別したい場合は、依然として === undefined による明示的な判定が必要です。

判定手法の比較表

手法 undefined判定 nullの扱い 未宣言変数 主な用途
x === undefined ○(厳密) 区別する ReferenceError 宣言済みの値を厳密に判定
typeof x === "undefined" 区別する 安全(エラーなし) 宣言の有無が不明な変数
x == undefined nullも一致 ReferenceError null/undefinedをまとめて判定
x == null nullも一致 ReferenceError Nullishの簡易判定イディオム
x ?? 既定値 -(既定値補完) nullも対象 ReferenceError 既定値の付与

落とし穴

注意したいポイント
  • 未宣言変数を直接比較しない: x === undefinedx が未宣言だと ReferenceError になります。宣言の有無が不明なら typeof を使います。
  • == は null も拾う: x == undefinedxnull でも true です。undefined だけを判定したいなら === を使います。
  • 「未定義プロパティ」と「値がundefinedのプロパティ」は === では区別不可: 区別が必要なら "prop" in obj を併用します。
  • グローバル undefined の再代入は現在のJavaScriptでは不可: 現代の仕様ではグローバルの undefined は書き換え不可(読み取り専用)です。古い環境向けに void 0 を使う流儀もありますが、通常は undefined をそのまま使って問題ありません。なお関数内などのローカルスコープで undefined という名前の変数を新たに宣言することは可能なので、変数名として使うのは避けます。

よくある質問(FAQ)

Q1. 結局、x === undefinedtypeof x === "undefined" のどちらを使えばよいですか?

変数が宣言済みであることが確実なら x === undefined が簡潔で読みやすく、おすすめです。変数が宣言されているかどうか分からない(未宣言の可能性がある)場合は、エラーにならない typeof x === "undefined" を使ってください。

Q2. undefinednull をまとめて判定したいときは?

x == null と書くと、xnull または undefined のときに true になります。意図的に「Nullishかどうか」を判定する定番のイディオムです。値の取り出しと既定値の付与をまとめて行いたい場合は x ?? 既定値 が便利です。

Q3. if (x) だけで undefined を判定してはいけませんか?

if (x)x が「falsyな値」のときに false になります。falsyには undefinednull のほか、0""(空文字)・falseNaN も含まれます。そのため 0 や空文字を正当な値として扱いたい場合、if (x) では undefined と区別できません。undefined だけを判定したいなら、明示的に x === undefined を使ってください。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 記述方法
  2. コメント
  3. 変数の宣言
  4. 関数
  5. 演算子
  6. 条件文
  7. 配列
  8. 連想配列
  9. ループ処理
  10. 非同期処理
  11. 同期処理
  12. 確認ウィンドウを表示する方法
  13. 文字の置換
  14. base urlを取得する方法
  15. formのsubmit前にjavascriptを呼び出す方法
  16. undefinedのイコール判定
  17. Javascript のみで form を post で submit する方法

最近更新/作成されたページ