JavaScript の数値チェックに isNaN を使ってはいけない理由
JavaScript の数値チェックに isNaN を使うのは「あり」か「なし」か?
答えは「なし」です。
なぜなら isNaN 関数は「数値であることをチェックする」関数ではなく「数値でないことをチェックする関数」だからです。チェックする引数の値に制約があるなら、isNaN で事足りるかもしれません。それでも、きちんと関数の仕様を理解しておかないとバグの温床となるため注意が必要です。
なぜ JavaScript の数値チェックに isNaN を使ってはいけないのか
そもそも NaN は Not a Number の略です。日本語に訳すと「数字ではない」になります。「数字ではない」の反対は「数字である」にも関わらず、isNaN の利用を否定するのは JavaScript の仕様に依るところがあります。
指数表記の e が数値扱いになる
まず最初の例として指数表記の扱いです。指数表記とは 10 の n 乗を「e+n」のように表記することです。
例えば Excel のセルに数字で「100000000000」と桁の大きな数字を入力すると「1E+11」のように勝手に変換される経験はありませんか?このアルファベットの E を使って表現されたのが指数表記です。
実は JavaScript でも同様の表現をすることができます。意図して指数表記で表現しているのであれば話は別ですが、一般的に指数表記で数字を表現することはありません。つまり、意図せず入力された指数表記が数値チェックを難なくスルーしてしまう問題が起こります。
ただプログラム的には数字として扱うのが正しいルールなので、このような表現方法でも数字扱いとなることを理解しておけば大丈夫です。
null 値が true になる問題
isNaN を使ってはいけない最大の理由がここにあります。引数の値によって isNaN が何を返却するか一覧にまとめたのでご覧ください。
引数の値 | 返却値 |
---|---|
数字 | false |
文字列 | true |
undefined | true |
null | false |
true | false |
false | false |
残念ながら null を渡すと false がリターンされます。これは null が数値の 0 として変換されてしまう JavaScript の仕様によるものです。同様に、true や false も各々 1 と 0 に変換されるため、false を返却します。
さすがに入力データが null の場合に 0 として取扱うのは無理があります。では事前に null は boolean のチェックをしたり、e が含まれていないことを確認しますか?そこまで実装するなら、わざわざ isNaN を使わなくてもいいのではないでしょうか。
isNaN を使わずどうやって数値チェックするのか
Web システムに組み込む数値チェックの場合、入力項目に応じた数値チェック関数を用意すべきです。例をいくつか挙げておきましょう。
- 整数入力チェック関数 ……… 小数なし、日本円の入力チェック等に使用
- 小数入力チェック関数 ……… 小数あり、外貨の入力チェック等に使用
- マイナス値チェック関数 ……… マイナスを許容してチェックする関数
これらの条件を組み合わせるだけでも、かなりの数の関数が必要になります。ここまできたら、isNaN をどう組み込むか考えるよりも、条件に応じた正規表現のチェック関数を用意したほうが簡単です。
正規表現を利用した数値チェック関数については次のページでまとめているので、よろしければ参考にしてください。