最新の JavaScript を最速で学ぶ!

プログラミングアカデミー ゼロプラスワン

JavaScript

数値かどうか、型を判定する isNumber と、テスト駆動開発

更新日:

前回の記事で数値について扱いました。今回は、数値かどうかの型を判定します。

数値かどうかを判定する。なぜか昔から間違ったコードが正しいものとして紹介されている。

JavaScript で数値かどうかを判定するために、どういうコードを書くのが正しいんだっけ?と思って、グーグルで[JS isNumber]で検索してみました。

うひゃーーーーー!目も当てられません。グーグルで上位数件にでてくる、JavaScriptコードでのisNumber関数系の処理が、めちゃくちゃですごいです。JavaScript って罠が多いし、その言語の特性を認識してない人が多いから、こんなことになるのでしょうか。

嘘、を並べているわけではないのですが、実用的ではないテクニックを載せているサイトが多いです。JavaScriptを教える側の人ですら、しっかりと理解しているわけではないということですね。

そのように使っては駄目だ。というアンチパターンを学んでしまってそれが正解だと思いこむと、将来苦しくなるだけなのではないかな、と思ったりもします。理解していない、のではなく、間違った理解をしている、というのは問題がより複雑になってしまいます。JavaScript恐るべしです。

どのような間違いをしてはいけないという一応示しておきましょうか。

JavaScript で数値判定 - にょきにょきブログ

こちらの isNumber では、なぜか、引数に文字列が渡っているのに、数値として正しいと判定するisNumber関数を作っています。これは....。こんな関数は実用的ではないでしょう。文字なのに数値判定されたらわけわかりません。数値判定と数値に変換可能かどうかの判定とは、別関数にしなければいけないのに....

JavaScriptで値が数値かどうかチェックする:isNaN() | UX MILK

数値判定に isNaN 使うとかって、どうしたらいいのでしょうか....めちゃくちゃですね。サンプルコードの結果も無茶苦茶。「trueやfalseも数値として扱われます。」みたいな。このサイト、確か相当な有名サイトなはずなのですが......大丈夫でしょうか....

$.isNumeric() | jQuery 1.9 日本語リファレンス | js STUDIO


jQueryは極めて有名な、JavaScript黎明期によく使われたデファクトスタンダード的なライブラリです。このjQueryのisNumeric自体が、文字列を引数にとってもOKとしていた仕様だったようです。最初に作ってしまったから今更修正するわけにいかなかったのか。こんな実装。上級者は許容しないでしょう。もうjQueryの時代ではなくなってきているので、よかったです。

数字判定 | JavaScript逆引き | Webサイト制作支援 | ShanaBrian Website


ここも上位に上がっていた様子でしたが、他のサイトと同じ理由で、望ましい 数値判定とはいえません。

通常の数値かどうかはisNaN関数じゃなくてisFinite関数 - 三等兵


試行錯誤の結果がたくさんのっています。isFiniteについて紹介しているのは、とても助かりました。

数値かどうかを判定する、完全なコード

ということで、うちのサイトが一つの正解を示しますね。数値判定はこのようにやります。というか、実に簡単なことしかやっていないのです。なぜこの簡単なコードを、多くのサイトが間違うのか....JavaScriptの基礎中の基礎ができていないというかなんというか....まあ、いいのですが。

基礎をちゃんと理解したい人は、このようなコードを書くのがよいでしょう。

これで、引数が数値型なのかそうじゃないのかを判定することができます。文字列を引数として渡したら、いくら数値を表していても、「数値ではないよ」という事を示してくれないと、実際のプログラミングの場面では困るわけです。

isFiniteでは NaN(数値型だけど数値じゃないを表す値→使わねーよこんな理不尽な定数) や Infinity(無限大を表す数値定数みたいなやつ→使わなーい!たぶん一生使わない!) は Falseになります。なので inFiniteを組み込んでいる、この isNumberではNanやInfinityは「数値ではない!」と判定するようにしました。

プログラミングの実用上、たとえば、計算結果に数値が入ってきてその結果で更に計算する場合、どこかで NaN や Infinity が入ってくると結果が正しく計算できない、ということになるので、「数値ではない!」と判断することが実用的だったりします。。isNumber は「この値は(計算することができる)数値なのか?」と判定するために使われるので、NaN や Infinity という、特殊、というか、変、な値は、数値の仲間には加えたくないのです。

完全なコードを、完全にするためのテスト駆動開発コード

この isNumber が、ほぼ完全だと言えるためには、しっかりとした動作確認をするべきなんです。この関数がちゃんと動くかどうかのテストを書いて動きをたしかめるということになります。

これはテスト駆動開発といって、最近、主流になりつつある開発スタイルになります。

この、checkEqual 関数を作って、動作確認するということは、多くの開発者がこの領域まで到達はしていない、どちらかというと、スーパーテクニック級の開発スタイルといえますので、身につけておくと、他の人達よりも一歩も二歩も十歩も百歩も抜きん出た、優れたプログラマになれると思います。

サンプルコードというのはこのように書くものだということを学んでおいてください。これが、後々、プログラマとしてのあなたの腕をあげてくると思います。

追記:文字が数値に変換可能かどうかを判定する

そういえば、多くのサイトでは、isNumerが「数値かどうか」だけではなく「文字が数値に変換可能か」を見るためにもつかわれていて、わけわからなくて実用的ではない様子でした。

今回の記事で紹介した「isNumber」はそんな機能はなく文字列は数値に変換可能だろうとそうじゃなかろうと「数値じゃない!」と判定するように作っています。

では「文字が数値に変換可能か」を判断したい場合にはどうするのか、というと、私の場合は、そういう場合どうするかというと「ConvertToNumber 文字を数値(整数とか小数)に変換する」とか、「ConvertToInt 文字を整数値に変換する」関数を用意して、それを使って変換して、変換できなければ、null を返すものを作っています。

こちらから「ConvertToNumber」や「ConvertToInt」を検索してもらうと、ソースコードを読むことができるので、そちらを参照してみてください。

エンジニアとして、「数値かどうか」と「文字だけど数値に変換可能かどうか」を同じ関数の機能としてまとめるべきではない、というのは、通常の優秀なエンジニアだと、誰でも理解できることです。これを理解していない人が、プログラミングを教えていることで、ひどく雑なプログラムコードが世の中にあふれてしまうんだろうな、と思ってしまいます。

細かいことですが、プログラマなら、細かいことにこだわるからこそ、正確で不具合(バグ)の少ないよいものが作れるようになるんですよ。

JavaScriptの癖を見抜いて、よいソースコードを書くプログラマになっていってください。

-JavaScript

Copyright© プログラミングアカデミー ゼロプラスワン , 2019 All Rights Reserved Powered by STINGER.