isNaN()

isNaN() 関数は引数が NaN (非数) かどうかを判定します。isNaN 関数の型強制は興味深いルールを持つことに注意してください。値が非数かどうかを判定する代用方法として、ECMAScript 2015 で定義されている Number.isNaN() が使用できます。

構文

isNaN(value)

引数

value
テストされる値。

返値

もし引数が NaN であるならば true を返し, そうでなければ false を返します。

解説

isNaN 関数の必要性

JavaScript にあるその他すべての値とは違い、ある数値が NaN であるかの判定に等値性評価演算子(== と ===)を使用することはできません。なぜなら NaN == NaNNaN === NaN はどちらも false と評価されるからです。そこで、isNaN が必要となります。

NaN 値の生成条件

NaN の値は算術演算の結果が未定義表現不可能な値となった時に生成されます。こうした値が常にオーバーフロー状態を表現するわけではありません。NaN はプリミティブな数値が利用不可能といった、非数値を数値へと型強制した結果生成されることもあります。

例えば、ゼロをゼロ除算した場合の結果は NaN になりますが、その他の数をゼロ除算した場合は異なります。

特殊な場合における厄介な動作

isNaN 関数の定義はごく初期のバージョン以降、数値ではない引数における振る舞いが分かりにくいものとなっていました。isNaN 関数の引数が数値型ではない場合、その値はまず数へと型強制されます。その結果の値はその後 NaN かどうかがテストされます。このようにして、数値型に型強制される際に結果が NaN ではない数値となる非数値(とりわけ型強制されると 0 や 1 の値になる空文字列や真偽値プリミティブ)に対しては、予想外なことに "false" が返されます【訳注: 「NaN でない」という結果から「数値である」と誤って解釈されてしまう】。無論、例えば空文字列は「数ではありません」。この混乱は、"not a number" (数ではない)というこの用語が IEEE-754 浮動小数点数定義で表現された数において特別な意味があるという事実に起因しています。この関数は、「この値を数値型に型強制した場合、IEEE-754 における 'Not A Number' という値になりますか?」という質問に答えるものとして解釈すべきです。

ECMAScript 2015 では Number.isNaN() 関数が存在します。Number.isNaN(x)xNaN かどうかをテストする確実な方法です。しかしながら Number.isNaN においても、NaN の意味は単純ではない明確な数値的意味を持つ "not a number" のままです。Number.isNaN が利用できない場合、xNaN かどうかを確実にテストする代わりの方法として (x != x) という式があります。この式の結果は信頼性のない isNaN が引き起こす誤検出の影響を受けません。

isNaN に対する polyfill の一つの例は以下のようになります(この polyfill は NaN が自分自身と常に等しくならないという特徴を利用しています):

var isNaN = function(value) {
    var n = Number(value);
    return n !== n;
};

isNaN(NaN);       // true
isNaN(undefined); // true
isNaN({});        // true

isNaN(true);      // false
isNaN(null);      // false
isNaN(37);        // false

// strings
isNaN('37');      // false: "37" は非数でない数値 37 に変換される
isNaN('37.37');   // false: "37.37" は非数でない数値 37.37 に変換される
isNaN("37,5");    // true
isNaN('123ABC');  // true:  parseInt("123ABC") の結果は 123、しかし Number("123ABC") の結果は NaN
isNaN('');        // false: 空文字列は非数でない 0 に変換される
isNaN(' ');       // false: 半角スペースからなる文字列は非数でない 0 に変換される

// dates
isNaN(new Date());                // false
isNaN(new Date().toString());     // true

// isNaN が信頼性に欠ける理由となる誤検出の例
isNaN('blabla');   // true: "blabla" が数値に変換される。
                   // 数値への変換が失敗し NaN が返される。

特殊な場合における便利な動作

isNaN() のふるまいを考慮した別の使用方法があります。isNaN(x)false を返す場合、NaN を返すことなく算術式内で x を使用できます。true を返す場合、x を使用すると全ての算術式で NaN を返すことになります。これはつまり、JavaScript において isNaN(x) == true という式は、x - 0 という式が NaN を返すかどうか、というケースと同等である(JavaScript では x - 0 == NaN は常に false を返すため、このことを確認できませんが)ということです。実際、isNaN(x)isNaN(x - 0)isNaN(Number(x))Number.isNaN(x - 0)、そして Number.isNaN(Number(x)) は常に同じ値を返し、JavaScript では isNaN(x) がこれらの条件を表す最も短い形式となります。

例えばこの動作を使って、ある関数への引数が算術処理可能か(数値として利用できるか)どうかをテストするのに利用し、そうでない場合はデフォルト値などを与えるようにできます。この方法によりコンテキスト次第で値を暗黙的に変換する汎用性の高い JavaScript 関数を作成できます。

仕様書

仕様書
ECMAScript (ECMA-262)
isNaN の定義

ブラウザーの互換性

BCD tables only load in the browser

関連情報