たまたま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つ関数が追加されるのかしら。