このページはコミュニティーの尽力で英語から翻訳されました。MDN Web Docs コミュニティーについてもっと知り、仲間になるにはこちらから。

View in English Always switch to English

NaN

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since 2015年7月.

NaN はグローバルプロパティで、非数 (Not-A-Number) を表す値です。

試してみましょう

function sanitize(x) {
  if (isNaN(x)) {
    return NaN;
  }
  return x;
}

console.log(sanitize("1"));
// 予想される結果: "1"

console.log(sanitize("NotANumber"));
// 予想される結果: NaN

Number.NaN と同じ数値です。

NaN のプロパティ属性
書込可能不可
列挙可能不可
設定可能不可

解説

NaN はグローバルオブジェクトのプロパティです。言い換えれば、グローバルスコープにある変数です。

最近のブラウザーでは、NaN は構成不可かつ書き込み不可のプロパティです。そうでない場合でも、これを上書きすることは避けてください。

NaN を返す演算には 5 種類があります。

  • 数値への変換に失敗した(parseInt("blabla")Number(undefined) 等の明示的なもの、Math.abs(undefined) のような暗黙的なもの)
  • 結果が実数値にならない算術演算(Math.sqrt(-1) など)
  • 不確定形(0 * Infinity1 ** InfinityInfinity / InfinityInfinity - Infinity、など)
  • オペランドが NaN である、または NaN を取得するメソッドや式(7 ** NaN7 * "blabla" など。このことは NaN が伝染性を持つことを意味します。
  • 不正な値を数値として表す必要があるその他の場合(不正な Date である new Date("blabla").getTime()"".charCodeAt(1) など)

NaN とその挙動は JavaScript が発明したものではありません。浮動小数点演算におけるその意味づけ(NaN !== NaN を含む)は IEEE 754 によって指定されています。NaN の挙動には以下が含まれます。

  • 数学演算(ただしビット演算を除く)においてNaNが関与する場合、結果は通常NaNとなります。(下記の反例を参照してください。)
  • 関係演算子(><>=<=)のいずれかのオペランドが NaN の場合、結果は常に false となります。
  • NaN は、他の値(別の NaN 値を含む)とは等しくない(==!====!==)を含む他のいかなる値とも等しくない。

NaN は JavaScript で偽値の値の一つと同時にあります。

NaN に対する検査

ある値が NaN かどうかを判断するには、Number.isNaN() または isNaN() を使用すると最も明確に判定できます。あるいは、NaN は自身と等しくない唯一の値であるため、x !== x のような自己比較で検査することも可能です。

js
NaN === NaN; // false
Number.NaN === NaN; // false
isNaN(NaN); // true
isNaN(Number.NaN); // true
Number.isNaN(NaN); // true

function valueIsNaN(v) {
  return v !== v;
}
valueIsNaN(1); // false
valueIsNaN(NaN); // true
valueIsNaN(Number.NaN); // true

ただし、 isNaN()Number.isNaN() には違いがあることに気をつけてください。前者は、値そのものが NaN であったり、値の変換の結果 NaN になる場合に true を返します。後者は値そのものが NaN のときにだけ true を返します。

js
isNaN("hello world"); // true
Number.isNaN("hello world"); // false

同じ理由で、長整数値の場合は isNaN() ではエラーが発生しますが、 Number.isNaN() では発生しません。

js
isNaN(1n); // TypeError: Conversion from 'BigInt' to 'number' is not allowed.
Number.isNaN(1n); // false

さらに、配列メソッドの中には NaN を探せないものもあれば、探せるものもあります。具体的には、インデックス検索メソッド(indexOf()lastIndexOf())は NaN を探すことはできませんが、値検索メソッド(includes())は探すことができます。

js
const arr = [2, 4, NaN, 12];
arr.indexOf(NaN); // -1
arr.includes(NaN); // true

// 適切に定義された述語を受け入れるメソッドは常に NaN を探すことができる
arr.findIndex((n) => Number.isNaN(n)); // 2

NaN とその比較について詳しくは、等価性の比較と同一性を参照してください。

明確に識別可能な NaN 値

2 つの浮動小数点数が異なる二進表現を持ちながらも両方とも NaN となる可能性があります。これは IEEE 754 エンコード方式において、指数が 0x7ff で仮数部が0でない浮動小数点数はすべて NaN となるためです。JavaScript で、型付き配列を使用してビット単位の操作を行うことができます。

js
const f2b = (x) => new Uint8Array(new Float64Array([x]).buffer);
const b2f = (x) => new Float64Array(x.buffer)[0];
// NaN のバイト表現の取得
const n = f2b(NaN);
const m = f2b(NaN);
// 符号ビットを変更する(NaN には影響しない)
n[7] += 2 ** 7;
// n[0] += 2**7; ビッグエンディアンの処理系のため
const nan2 = b2f(n);
console.log(nan2); // NaN
console.log(Object.is(nan2, NaN)); // true
console.log(f2b(NaN)); // Uint8Array(8) [0, 0, 0, 0, 0, 0, 248, 127]
console.log(f2b(nan2)); // Uint8Array(8) [0, 0, 0, 0, 0, 0, 248, 255]
// まず最初のビットを変更する。これは仮数の最下位ビットであり、NaN には影響しない。
m[0] = 1;
// m[7] = 1; ビッグエンディアンの処理系のため
const nan3 = b2f(m);
console.log(nan3); // NaN
console.log(Object.is(nan3, NaN)); // true
console.log(f2b(NaN)); // Uint8Array(8) [0, 0, 0, 0, 0, 0, 248, 127]
console.log(f2b(nan3)); // Uint8Array(8) [1, 0, 0, 0, 0, 0, 248, 127]

暗黙に NaN をエスケープ

NaN は数学演算を通じて伝播するため、通常は計算の最後に一度 NaN を検査するだけでエラー状態を検出できます。NaN が黙って無視される唯一の場合は、指数が 0べき乗を使用する場合であり、この場合基数の値を検査せずに即座に 1 を返します。

js
NaN ** 0 === 1; // true

仕様書

Specification
ECMAScript® 2026 Language Specification
# sec-value-properties-of-the-global-object-nan

ブラウザーの互換性

関連情報