タイトルは半分釣りです。
NaN(Not a Number)はNumberじゃないって言ってるのにtypeofしたらnumberが返ってきたり、(({}).toString.call(NaN)みたいな厳密な型チェックしてもNumberが返ってきくる)NaN === NaNがfalseになったり(例えばparseInt("a")とparseInt("b")は両方NaNだけど違うもんね)する不思議なヤツです。
普通の数字かどうやって見分けるのかといえば、window.isNaN()やNumber.isNaN()を使うのですが、今回はその関数を簡単に作ってみたいと思います。
Number.isNaN()が厳密に**NaNかどうかをチェックしているのに対し、window.isNaN()は数ではないか**を見ています。
簡単な例を出せば、
isNaN("x") // -> true
Number.isNaN("x") // -> false
となります。
今回作るのは、Number.isNaN()の方です。
ソースコード
myIsNaN =_=>_!==_ ;
myIsNaN(NaN) // -> true
なんか記号がいっぱいでわかりませんね。わざわざシンタックスハイライトを適用していないところに筆者の意地悪さがでています。
考え方
黒魔術っぽく見えますが分解して整理すると簡単です。
myIsNaN = _ => _ !== _ ;
勘の良い方は気づかれたんじゃないでしょうか?
_はJavaScriptでは他の文字と同じように変数名として使用できる記号です。何か他の文字に変えてみましょう。
myIsNaN = value => value !== value ;
なんだ、ただのアロー関数ですね。
これで謎が解けました。
念の為見すぎて目にタコができた形式にするとこうなります。
function myIsNaN(value){
return (value !== value);
}
NaNの性質の一つ、「両方NaNでも等価にならない」を応用してるわけですね。
ちなみに、window.isNaN()の方は、Number型でないものもtrueを返すので、
myIsNaN =_=>({}).toString.call(_)!=="[object Number]"||_!==_
こうなります。また、ド・モルガンの法則を利用して、
myIsNaN =_=>!(({}).toString.call(_)==="[object Number]"&&_===_)
こういう風にも書けます。
さいごに
アロー関数たのちい