たまたまTwitterを見てたら以下のようなツイートを見かけました。
つまり、 isNumber っていう関数を作るなら一旦Numberでキャストした値と同一かどうかを比較すれば良いと。おそらく NaN を省いた number 型を true にしたいのかなという感じがする (NaN === NaN は必ず false)。
ただこれには問題があるらしく、 V8 のOptimizerリーダーである bmeurer から下記のようなレスが付いてました。
「 Number() では意図しない副作用があるかもしれない」という意味のレス。最初意味がわからなくて、「おや?」と思ったんですけど、その後で補足が。
「ToPrimitive関数が呼ばれてしまい、意図しないJSの動きをするかも。」とのこと。
つまり、
var a = {
x: 1,
[Symbol.toPrimitive]: function() {
this.x++;
return this.x;
}
};
みたいなオブジェクトがあったら、 Number 関数が呼ばれる度に a.x がインクリメントされてしまう。
$ node > Number(a)
<- 2
$ node > Number(a)
<- 3
$ node > Number(a)
<- 4
これだけじゃなくて、 +a でも呼ばれるはず
$ node > +a
<- 5
$ node > +a
<- 6
$ node > +a
<- 7
上記の条件(NumberだけどNaNをfalseにしつつ、副作用を伴わない)を満たすisNumber関数を作るなら、横着せずにちゃんと typeof a === 'number' と Number.isNaN でチェックするのがいいんだろう。
いやでも待てよ、それだとすると、副作用を伴わずにNumber型にキャストするっていう手段はないのか・・・?どうしよう、って思ったら Dr. Axel 先生からの締め。
parseNumber っていう関数あるといいのかもねーっていう。こうしてJSにまた1つ関数が追加されるのかしら。



