NaNをisNaNで判定しようとするとおかしな事になる可能性があるので気をつけましょうって話です。
Effective JavaScriptで紹介されていたのですが、知らなかったのでメモです。
isNaNの挙動
標準で用意されているisNaNにNaNを渡すと確かにtrueが返ります。
ただ、暗黙の型変換によって引数を数値へと変換してしまう為、NaN自身でなくても、NaNへと変換される類のものに対してもtrueを返してしまいます。
isNaN(NaN); // true
isNaN("foo"); // true
isNaN(undefined); // true
isNaN({}); // true
isNaN({ valueOf: "foo" }); // true
isNaNはNaNであるかの判定ではなく、引数が数値へ変換可能かどうかの判定に使われるみたいです。
NaN判定のイディオム
Effective JavaScriptでは、NaNが自身との等号判定でfalseを返すという性質を利用して、以下のようなイディオムが紹介されていました。
NaN === NaN // falseを返す!!!
function isReallyNaN(x) {
return x !== x; // xがNaNであればtrue, それ以外ではfalse
}
確かに、これで判定出来ますね。
Number.isNaN
ECMAScript6ではNumber.isNaNというのが策定されて、きちんとNaNを判別出来るようになったようです。
Number.isNaN(NaN); // true
Number.isNaN('NaN'); // false
このページを参考にしました。
標準で判定用の関数が用意されるなら、そちらを使った方が良さそうですね。