web-dev-qa-db-ja.com

JavaScriptでNaNをテストするにはどうすればよいですか?

変数xがあり、xがNaNに設定されているかどうかをテストします。それ、どうやったら出来るの?

私の最初の本能は、おそらく次のようにテストすることです。

_if (x === NaN) {  ...
_

愚かなウサギ、いや、それはあまりにも簡単でしょう。 NaNはSQLのNULLに似ており、それ自体も何とも等しくありません。

しかし、見てください、isNaN()と呼ばれる関数があります-多分それはそれをするでしょう!

いいえ、私が知る限り、isNaN()はまったく価値がありません。

たとえば、isNaN([""])は正しくfalseを返しますが、isNaN(["."])はtrueを返します。あなたは私がこの欠陥についてどのように学んだか知りたくありません。

どうすればいいですか?

結局のところ、私の質問は this one の複製ですが、選択した答えは間違っています。 正解 には、20%の賛成票があります。

37
Malvolio

よく読んでいると、質問に答えがあります。それが私が見つけた方法です。質問を入力して...ビンゴ。

NaNはSQLのNULLのようなもので、それ自体でも何とも等しくない」と書いたときのことを覚えていますか?私の知る限り、NaNはこのプロパティを持つJavascriptの唯一の値です。したがって、次のように記述できます。

var reallyIsNaN = function(x) {
   return x !== x;
};
22
Malvolio

簡易回答

ECMAScript-5ユーザーの場合:

#1
if(x !== x) {
    console.info('x is NaN.');
}
else {
    console.info('x is NOT a NaN.');
}

ECMAScript-6を使用している場合:

#2
Number.isNaN(x);

ECMAScript 5と6の両方で一貫性を保つために、Number/isNanにこの polyfillを使用することもできます

#3
//Polyfill from MDN
Number.isNaN = Number.isNaN || function(value) {
    return typeof value === "number" && isNaN(value);
}
// Or
Number.isNaN = Number.isNaN || function(value) {     
    return value !== value;
}

注:すべての場所で同じように機能し、最新のJSにも依存しない#1を使用してテストすることを好みます。 (常に正しい結果が得られます。驚きはありません!)


詳細な説明:

これが素晴らしいNaNです

NaN == NaN; // false
NaN === NaN; // false

これをJavaScriptのせいにしないでください。他の言語でもこのように動作するはずのNaNは、 偽のNaN値を返すすべての比較の論理的根拠に基づいています

isNaNが救世主になりますが、次のようなシナリオでは少し異なる動作をします

isNaN(undefined); // true
isNaN({});        // true
isNaN("lorem ipsum"); // true

上記の結果を見て、奇妙な顔をしていた。そしてここにMDNからの理由があります

IsNaN関数への引数が数値型ではない場合、値は最初に数値に強制変換されます。次に、結果の値をテストして、NaNかどうかを判断します。

では、非数値変数についてNaNをテストする方法は何でしょうか?私はいつも次のように行きます

if(x !== x) {
    console.info('Is a NaN');
}
else {
    console.info('Not a NaN');
}

ECMAScript-6/JavaScript-2015アップデート

ECMAScript-6にも同じことがありますか?うん...

Number.isNaN(x); // true

ES6の実装は、上記のような場合にも役立ちます。

Number.isNaN(undefined); // false
Number.isNaN({}); // false    
Number.isNaN("lorem ipsum"); // false

一方、ECMAScript-5グローバル関数isNaNは、上記の場合にtrueに出力しますが、これは期待と一致しない場合があります。

44
dopeddude