JavaScript では、文字列と数値を明示的には区別せず、使われる場面で区別している。 その使われる場面がくせものだ。私が最初に遭遇したのもこの問題である。 結論からいうと、文字列を表す数字はNumber()関数を使って数値に変換する必要がある。 同時に、数値として正しくなければエラー処理を行なう必要がある。
まず、失敗した例を説明しよう。 フォームに欄を2つ用意し、その欄の和を表示するプログラムを JavaScript で書いた。 欄に2と3を入れると、答が 23 と表示されてしまった。 これは欄の字が数値としてではなく文字列として認識され、 その結果 + が数値の加算ではなく文字列の連結として働いたためである。正しい答5を得るためには、 2つの欄から得られる文字列のいずれにも数値化の関数を働かせて、数値にする必要がある。
さて、数値にするには、どうすればいいだろうか。 一つのテクニックは、数値の 0 を引く方法である。 その他、関数を使う方法もある。関数はどれがいいだろうか。 JavaScript では、4つの関数がある。Number() のほか、 parseInt()、parseFloat()、eval() がある。 これらの働きをまとめた表を作った。 ただし、eval() は安全性の面から数値にするために使うことは非推奨であるので、 2020 年に削除した。 以下、この表について説明する。
1. 変換後とは、数が変換されたあと、どの型になるかを示している。 parseInt を除き、小数になる。
2. 非数値とは、入力に数値として正しくない文字が現れたときの挙動である。 parseFloat、parseIntは、文字列の先頭から正しいところまでを切りとって返すのに対し、 Number は NaN を返す。eval はエラーとなり、以降のプログラムが中断される。 従って、厳密なチェックには Number が向いている。 また、入力に 1.5e1 とした場合、小数では 1.5 * 101 = 15 で整数であるが、 parseInt の入力では小数点を読んだときに整数ではないとみなされるので、答は1となる。
3. 文字列実行とは、引数の文字列を式として実行できることを示す。2+3 という文字列を与えると、 eval では 5 が答となる。
4. N 進数対応とは、答をN進数表示できることをいう。 parseInt では、2進数から36進数までの表記ができる。
チェックによりプログラムが中断してはならない。 また、小数を表すべき場合で整数を表してはいけない。 数値となる文字列は厳密にチェックすべきであるから、 これら4種類の関数のなかではNumber()が最適といえる。
なお、対象が小数である場合はいいが、整数を対象に厳密なチェックを行なうには、 いい関数がない。 対象文字列 s に対して、parseFloat(s) == parseInt(s) であることを確かめるとか、 適切な正規表現を考えるとか、適当な手段が必要である。
必ずしも適切とはいえないが、例えば、/^[-+]?\d+$/という表現である程度は表せる。 最初は/[-+]?\d+/と書いて失敗した。失敗した理由はお分かりですよね。
TypeScript を使うのがよいと思われる(2020-03-25)。
まりんきょ学問所 ≫ JavaScript 手習い ≫ 数値への変換