NaNとは?
プログラミングで計算処理を書いていると、突然画面に「NaN」と表示されて戸惑った経験はありませんか?NaNは「Not a Number」の略で、日本語に訳すと「数値ではない」という意味です。
NaNは、数値として計算できない処理が行われたときに返される特殊な値です。例えば、文字列を数値に変換しようとして失敗したとき、0を0で割ろうとしたとき、数値以外のものに算術演算を行ったときなどに発生します。
ここで重要なのは、NaNは「エラー」ではないということです。プログラムはNaNが出ても停止しません。NaNという特殊な値を返して、処理を続行します。だからこそ、気づかないまま計算結果がNaNのまま後続の処理に渡されてしまうバグが起きやすいのです。
undefinedとは?(おさらい)
undefinedは「値がまだ定義されていない」ことを示す特殊な値です。変数を宣言しただけで値を代入していないとき、存在しないオブジェクトのプロパティにアクセスしたとき、関数がreturn文なしで終了したときなどに発生します。
undefinedは「そもそも値が入っていない」状態であり、NaNの「計算を試みたが数値にならなかった」とは根本的に異なります。
NaNとundefinedの決定的な違い
違い①:発生する場面が違う
NaNは数値計算の文脈で発生します。何かを数値として処理しようとしたけれど、数値に変換できなかったときに現れます。一方、undefinedは変数や参照の文脈で発生します。値がまだ設定されていない状態を示します。つまり、NaNは「計算の失敗」、undefinedは「値の不在」です。
違い②:型(type)が違う
JavaScriptでtypeofを使うと、NaNは「number」型を返します。これは直感に反するかもしれませんが、NaNは「数値演算の結果として生まれた値」なので、数値型の一種として扱われます。一方、undefinedは「undefined」型を返します。この型の違いは条件分岐やバリデーション処理で重要になります。
違い③:比較演算の振る舞いが違う
NaNには非常に特殊な性質があります。NaN === NaN はfalseを返します。つまり、NaNは自分自身と等しくない唯一の値です。この性質を利用して、isNaN()やNumber.isNaN()で判定する必要があります。undefinedは通常の比較が可能で、undefined === undefinedはtrueを返します。
違い④:nullとの関係が違う
undefinedはnullと「==(緩い等価)」で比較するとtrueになります(undefined == null → true)。しかし、NaNはnullと比較してもfalseです(NaN == null → false)。NaNはどんな値と比較してもfalseを返す唯一の存在です。
実務でよくあるNaN・undefinedのバグパターン
パターン①:APIレスポンスの数値フィールドがnullのまま計算
APIから受け取ったJSONデータで、数値フィールドがnullやundefinedのまま計算すると、NaNが発生します。例えば、ユーザーの年齢フィールドが未入力でnullだった場合、そのままage + 1を計算するとNaNになります。対策としては、計算前にデフォルト値を設定する(例:const age = data.age ?? 0)のが有効です。
パターン②:DOM要素の値が空文字のまま数値変換
HTMLのフォーム入力値をparseInt()で変換する際、入力が空だとNaNが返ります。Number.isNaN()でチェックする習慣をつけましょう。
パターン③:非同期処理でデータ取得前にアクセス
非同期でデータを取得する前に変数にアクセスすると、undefinedになります。async/awaitやオプショナルチェイニング(?.)を活用して防ぎましょう。
NaN・undefinedの安全な判定方法
NaNの判定にはNumber.isNaN()を使いましょう。古いisNaN()はグローバル関数で、引数を数値に変換してからチェックするため、isNaN(“hello”)がtrueを返すなど直感に反する動作をします。Number.isNaN()は引数がNaN型かつNaN値であるときだけtrueを返すので、より安全です。
undefinedの判定にはtypeof演算子が最も安全です。typeof value === ‘undefined’でチェックすれば、変数が宣言されていない場合でもエラーにならずに判定できます。また、Null合体演算子(??)を使えば、undefinedやnullの場合にデフォルト値を簡潔に設定できます。
まとめ:NaNとundefinedの違い早見表
NaNは「数値演算の失敗結果」、undefinedは「値が未定義の状態」。型はNaNがnumber、undefinedがundefined。自分自身との比較は、NaNがfalse(NaN !== NaN)、undefinedがtrue。判定方法はNaNがNumber.isNaN()、undefinedがtypeof === ‘undefined’。よくある原因は、NaNが不正な数値変換、undefinedが未代入・未定義アクセスです。
この2つの違いを理解しておくと、「なぜ画面にNaNが表示されるのか」「なぜundefinedエラーが出るのか」を素早く切り分けてデバッグできるようになります。


コメント