ES6でisNaN関数を作るととてもアレになる。


タイトルは半分釣りです。

NaN(Not a Number)はNumberじゃないって言ってるのにtypeofしたらnumberが返ってきたり、(({}).toString.call(NaN)みたいな厳密な型チェックしてもNumberが返ってきくる)NaN === NaNfalseになったり(例えば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]"&&_===_)

こういう風にも書けます。

さいごに

アロー関数たのちい