JavaScript | 基礎構文:数値・演算 – isNaN

JavaScript JavaScript
スポンサーリンク

isNaNとは何か

isNaNは「値が数値ではない(NaN)かどうか」を判定するための関数です。JavaScriptには2種類あり、挙動が異なります。グローバル関数の isNaN は値を数値へ強制変換(型変換)してから NaN 判定を行い、Number.isNaN は型変換せずに「値そのものが NaN か」を厳密に判定します。

isNaN("foo");         // true(数値に変換できないので NaN とみなす)
Number.isNaN("foo");  // false("foo" は NaN ではない文字列)
Number.isNaN(NaN);    // true(値そのものが NaN)
JavaScript

基本の使い方と違いのポイント

グローバル isNaN の挙動

グローバル isNaN は、まず Number(…) で数値化を試みてから NaN かどうかを判定します。数値化できないものは「NaNとみなす」ため、直感に反する結果を返すことがあります。

isNaN("123");   // false(数値化できる)
isNaN("12px");  // true(数値化できない)
isNaN(true);    // false(true → 1 に変換される)
isNaN(null);    // false(null → 0 に変換される)
isNaN(undefined); // true(数値化できない)
JavaScript

Number.isNaN の挙動(推奨)

Number.isNaN は型変換をしないため、「本当に NaN かどうか」を判定できます。こちらを使うと、バグを避けやすくなります。

Number.isNaN(NaN);          // true
Number.isNaN(undefined);    // false
Number.isNaN("12px");       // false
Number.isNaN(Number("12px")); // true(変換した結果が NaN)
JavaScript

具体例で理解する

ユーザー入力の検証

文字列入力を数値に変換し、NaNならエラーメッセージを返す例です。判定には Number.isNaN を使います。

function toNumberSafe(s) {
  const n = Number(s);
  return Number.isNaN(n) ? null : n;
}

console.log(toNumberSafe("42"));   // 42
console.log(toNumberSafe("4 2"));  // null(変換失敗)
console.log(toNumberSafe("abc"));  // null
JavaScript

合計の計算で NaN を弾く

配列内の「数値化できなかった値」を除外してから合計します。

const raw = ["10", "x", "20", "", "3.5"];
const nums = raw
  .map(s => Number(s))
  .filter(n => !Number.isNaN(n));

const sum = nums.reduce((a, b) => a + b, 0);
console.log(nums); // [10, 20, 0, 3.5]
console.log(sum);  // 33.5
JavaScript

グローバル isNaN の落とし穴を確認

同じ入力でも結果が変わることがあるため、どちらを使うかが重要です。

console.log(isNaN(""));          // false("" → 0)
console.log(Number.isNaN(""));   // false(文字列は NaN ではない)

console.log(isNaN(" "));         // false(" " → 0)
console.log(Number.isNaN(" "));  // false

console.log(isNaN([]));          // false([] → 0)
console.log(Number.isNaN([]));   // false
JavaScript

実務での使い分け

入力バリデーションの基本方針

まず Number(…) や parseFloat(…) で数値化し、その「結果」に対して Number.isNaN で判定します。もとの値に対して直接 Number.isNaN を使っても、NaNではないため常に false になりがちです。

function parseAmount(s) {
  const n = Number(s);
  if (Number.isNaN(n)) return { ok: false, error: "数値に変換できません" };
  return { ok: true, value: n };
}
JavaScript

Object.is と NaN の比較

通常の比較演算子では NaN 同士が等しくありません。どうしても「NaN かどうか」を同一性でチェックしたい場面では Object.is を使えます。

NaN === NaN;           // false
Object.is(NaN, NaN);   // true
JavaScript

例題で練習する

例題1:安全な加算

2つの入力文字列を足し算します。どちらかが数値化できなければエラーとします。

function addInputs(aStr, bStr) {
  const a = Number(aStr);
  const b = Number(bStr);
  if (Number.isNaN(a) || Number.isNaN(b)) {
    return "入力が数値ではありません";
  }
  return a + b;
}

console.log(addInputs("10", "20")); // 30
console.log(addInputs("10", "x"));  // "入力が数値ではありません"
JavaScript

例題2:平均値の計算(NaN除外)

配列の文字列を数値化し、NaNを除いて平均を求めます。空配列対策も入れます。

function averageSafe(arr) {
  const nums = arr.map(Number).filter(n => !Number.isNaN(n));
  if (nums.length === 0) return 0; // デフォルト
  return nums.reduce((s, x) => s + x, 0) / nums.length;
}

console.log(averageSafe(["1", "2", "x", "3"])); // 2
console.log(averageSafe(["x", "y"]));           // 0
JavaScript

例題3:フォーム値の検証

金額の入力を受け取り、整数であることと NaN でないことをチェックします。

function validatePrice(s) {
  const n = Number(s);
  if (Number.isNaN(n)) return "数値にしてください";
  if (!Number.isInteger(n)) return "整数にしてください";
  if (n < 0) return "0以上にしてください";
  return "OK";
}

console.log(validatePrice("1000")); // "OK"
console.log(validatePrice("12.3")); // "整数にしてください"
console.log(validatePrice("abc"));  // "数値にしてください"
JavaScript

まとめ

isNaN は「NaN 判定」をするための関数ですが、グローバル isNaN は型変換を伴い、Number.isNaN は厳密判定を行います。入力の検証や数値変換では、まず Number(…) などで数値に変換し、その結果に対して Number.isNaN を使うのが安全です。落とし穴(空文字や空配列が 0 に変換されるなど)を避けるためにも、原則 Number.isNaN を選ぶことを覚えておくと安心です。

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