●JavaScriptで数値判定が必要な理由
私たち開発者にとって、ユーザーからの入力値をチェックすることは非常に重要です。
特に数値に関しては、計算処理を行う際に欠かせません。
○数値判定の重要性
ユーザーが入力した値が期待通りの数値であるかを判定することは、アプリケーションを安定して動作させるために不可欠です。
数値以外の値が混入していると、エラーが発生したり、意図しない結果になったりする可能性があります。
○バリデーションの一環として
数値判定は、ユーザー入力のバリデーションにおいて重要な役割を果たします。
例えば、年齢や金額など、数値のみを受け付けるフィールドがあるとします。
そこで文字列が入力されると、データの整合性が取れなくなってしまいます。
数値判定を行うことで、不正な入力を未然に防ぎ、データの一貫性を保つことができるのです。
○計算処理のために
JavaScriptでは、数値を使った計算処理を行うことが多々あります。
例えば、ショッピングカートで合計金額を算出したり、ポイント計算を行ったりする場面です。
これらの処理を正しく行うためには、扱う値が確実に数値であると保証されている必要があります。
数値判定を怠ると、「NaN」(Not a Number)というエラー値が発生し、計算結果が狂ってしまうかもしれません。
数値判定は、計算処理を適切に実行するための大前提なのです。
●数値の種類と判定方法の概要
JavaScriptで扱う数値には、主に2つの種類があります。それが整数と小数です。
この2つの数値型を理解し、適切に判定できるようになることが、数値処理の第一歩と言えるでしょう。
○整数と小数
整数は、正負の符号を持つことができ、小数点以下の値を持たない数値です。
一方、小数は小数点以下の値を持つことができます。
JavaScriptでは、両者を区別せずに「Number」という1つの型で表現します。
ただし、小数の計算には浮動小数点数特有の誤差が生じる可能性があるので、注意が必要です。
金額計算など、正確性が求められる場面では、整数で計算してから最後に小数点を付けるなどの工夫が必要かもしれません。
○文字列から数値への変換
ユーザー入力値は、一般的に文字列として受け取ります。
そのため、数値判定を行う前に、文字列を数値に変換する必要があります。
JavaScriptでは、以下のような方法で文字列を数値に変換できます。
Number()
関数は、文字列を数値に変換します。
変換できない場合はNaN
(Not a Number)を返します。
一方、parseFloat()
関数は、文字列を浮動小数点数(小数)に変換します。
これらの関数を使って、ユーザー入力値を適切な数値型に変換することが、数値判定の前提条件となります。
○NaNとは
NaN
は、”Not a Number”の略で、数値ではないことを表す特殊な値です。
上述のNumber()
関数やparseFloat()
関数で、数値に変換できない文字列を渡すと、NaN
が返ってきます。
NaN
は、自分自身と等しくない唯一の値です。
そのため、NaN
かどうかを判定するには、isNaN()
関数を使います。
数値判定を行う際は、NaN
のケースも考慮に入れる必要があります。
NaN
は数値ではないので、数値としては扱えないことを理解しておきましょう。
●正規表現を使った数値判定
文字列が数値かどうかを判定するには、正規表現を使うのが効果的です。
正規表現を使えば、数値のパターンにマッチするかどうかでチェックできます。
JavaScriptでは、正規表現を使った文字列のマッチングができるので、数値判定にも活用できるわけです。
○サンプルコード1:正の整数の判定
では早速、正規表現を使って、文字列が正の整数かどうかを判定するサンプルコードを見てみましょう。
この正規表現/^[1-9]\d*$/
は、次のような意味を持っています。
^
:文字列の先頭[1-9]
:1から9までの数字のいずれか1文字\d*
:数字(0から9)の0回以上の繰り返し$
:文字列の末尾
つまり、この正規表現は、「文字列の先頭が1から9までの数字で始まり、その後に0から9までの数字が0回以上続き、文字列の末尾に達する」というパターンにマッチします。
これは正の整数を表すパターンですね。
test()
メソッドは、正規表現とマッチするかどうかを真偽値で返します。
これを使うことで、文字列が正の整数かどうかを判定できます。
○サンプルコード2:正の小数の判定
同様に、正の小数を判定する正規表現を使ってみましょう。
この正規表現/^[1-9]\d*(\.\d+)?$/
は、先ほどの正の整数の正規表現に、小数点以下の部分を追加したものです。
(\.\d+)?
:小数点(.
)とその後に続く1文字以上の数字(0から9)の0回または1回の出現
これにより、小数点以下の部分があってもなくても、正の小数にマッチするようになります。
○サンプルコード3:0以上の数値の判定
ここで、0以上の数値(整数または小数)を判定する正規表現を見てみましょう。
この正規表現/^(?:0|[1-9]\d*)(?:\.\d+)?$/
は、次のような意味を持っています。
(?:0|[1-9]\d*)
:0または正の整数(?:\.\d+)?
:小数点以下の部分(オプショナル)
これにより、0以上の整数および小数にマッチするようになります。
○サンプルコード4:カンマを含む数値の判定
最後に、カンマを含む数値(例えば “1,234,567”)を判定する正規表現を見てみましょう。
この正規表現/^[1-9]\d{0,2}(?:,\d{3})*(?:\.\d+)?$/
は、次のような意味を持っています。
[1-9]\d{0,2}
:1から999までの整数(?:,\d{3})*
:3桁ごとのカンマ区切り(?:\.\d+)?
:小数点以下の部分(オプショナル)
これにより、カンマを含む数値(整数および小数)にマッチするようになります。
●数値判定に使える組み込み関数
正規表現を使った数値判定は強力ですが、JavaScriptには数値判定に使える便利な組み込み関数もあります。
これらの関数を使えば、数値判定をもっと簡潔に書くことができるでしょう。
○Number()
Number()
関数は、引数を数値に変換します。
変換できない場合はNaN
を返します。
Number()
関数は、数値への変換だけでなく、真偽値やnull、undefinedなども数値に変換します。
これを利用して、数値かどうかを判定することができます。
ここでは、Number()
関数で変換した結果が数値型(typeof
演算子で"number"
と判定される)であり、かつNaN
ではないことを確認しています。
○parseInt()
parseInt()
関数は、引数を整数に変換します。
変換できない場合はNaN
を返します。
parseInt()
関数は、文字列の先頭から数値として解釈できる部分までを取り出して整数に変換します。
数値として解釈できる部分がない場合はNaN
を返します。
○parseFloat()
parseFloat()
関数は、引数を浮動小数点数(小数)に変換します。
変換できない場合はNaN
を返します。
parseFloat()
関数は、文字列の先頭から数値として解釈できる部分までを取り出して浮動小数点数に変換します。
整数部分だけでなく、小数部分も含めて変換する点がparseInt()
関数と異なります。
○isNaN()
isNaN()
関数は、引数がNaN
かどうかを判定します。
isNaN()
関数は、引数がNaN
である場合にtrue
を返します。
引数が数値に変換できる場合はfalse
を返します。
この関数を使えば、NaN
のチェックを簡潔に書くことができます。
○isFinite()
isFinite()
関数は、引数が有限の数値かどうかを判定します。
isFinite()
関数は、引数が有限の数値である場合にtrue
を返します。
Infinity
、-Infinity
、NaN
、数値に変換できない文字列などはfalse
を返します。
この関数を使えば、有限の数値であるかどうかを簡単にチェックできます。
●TypeScriptでの数値判定
JavaScriptの数値判定方法について理解が深まってきたところで、今度はTypeScriptでの数値判定について見ていきましょう。
TypeScriptは、JavaScriptに静的な型システムを追加した言語です。
型チェックによって、コンパイル時にエラーを検出できるため、バグの少ないコードを書くことができます。
○TypeScriptの型チェック
TypeScriptでは、変数や関数の引数、戻り値に型を指定することができます。
これにより、意図しない型の値が代入されるのを防ぐことができるのです。
例えば、数値型の変数を宣言する場合は、次のように書きます。
ここでは、num
変数が数値型(number
型)であることを明示しています。
もし、この変数に数値以外の値を代入しようとすると、TypeScriptのコンパイラがエラーを報告してくれます。
このように、TypeScriptの型チェックを活用することで、数値でない値が紛れ込むのを防ぐことができます。
○サンプルコード5:TypeScriptでの数値判定
それでは実際に、TypeScriptを使って数値判定を行うサンプルコードを見てみましょう。
このisNumberValue
関数は、引数のvalue
が数値型であり、かつNaN
でないかどうかを判定しています。
引数の型はany
型にしていますが、これは任意の型の値を受け取れるようにするためです。
関数の戻り値の型はboolean
型にしています。
これにより、この関数が真偽値を返すことを明示しています。
TypeScriptでは、このように型を指定することで、関数の引数や戻り値の型を明確にし、型のミスマッチによるバグを防ぐことができます。
さらに、TypeScriptの型推論機能を使えば、明示的に型を書かなくても、変数の型を自動的に推測してくれます。
ここでは、num
変数に初期値として数値を代入しているので、TypeScriptはnum
変数の型をnumber
型だと推測します。
そのため、後から文字列を代入しようとするとエラーになります。
●比較演算子を使った大小判定
さて、ここまでは主に数値かどうかの判定方法について見てきましたが、実際のアプリケーション開発では、数値の大小を比較して条件分岐することも多いですよね。
例えば、ユーザーの入力値が0以上100以下の範囲内にあるかどうかをチェックするような場面です。
そこで登場するのが、比較演算子です。比較演算子を使えば、数値の大小関係を簡単に判定できます。
○不等号による比較
JavaScriptでは、不等号を使って数値の大小を比較できます。
主な比較演算子は次の通りです。
>
:大なり>=
:大なりイコール<
:小なり<=
:小なりイコール==
:等しい!=
:等しくない===
:厳密に等しい!==
:厳密に等しくない
この演算子を使って、数値の大小関係を判定するわけです。
○サンプルコード6:0以上かの判定
では実際に、比較演算子を使って数値が0以上かどうかを判定するサンプルコードを見てみましょう。
このisNonNegative
関数は、引数num
が0以上であればtrue
を、そうでなければfalse
を返します。
関数内では、>=
演算子を使って、num
が0以上かどうかを判定しています。
num >= 0
の結果がtrue
またはfalse
になるので、それをそのまま関数の戻り値としているわけです。
このように、比較演算子を使えば、数値の大小関係を簡潔に判定できます。
○サンプルコード7:正の数かの判定
同様に、数値が正の数(0より大きい)かどうかを判定するサンプルコードを見てみましょう。
ここでは、>
演算子を使って、num
が0より大きいかどうかを判定しています。
0は正の数に含まれないので、num > 0
がtrue
になるのは、num
が正の数の場合だけです。
○サンプルコード8:負の数かの判定
逆に、数値が負の数(0より小さい)かどうかを判定するには、<
演算子を使います。
num < 0
がtrue
になるのは、num
が負の数の場合だけですね。
このように、比較演算子を使えば、数値の大小関係を簡単にチェックできます。
ただし、比較演算子を使う前提として、比較対象が数値であることが保証されている必要があります。
数値かどうかのチェックと、大小関係のチェックを組み合わせることで、より厳密な条件判定ができるでしょう。
例えば、ユーザーの入力値が0以上100以下の数値であることを確認するには、次のような判定を行います。
このisValidScore
関数では、まずtypeof
演算子でscore
が数値型であることを確認し、さらに>=
と<=
を使ってscore
が0以上100以下の範囲内にあることをチェックしています。
すべての条件を満たす場合にのみtrue
を返すので、より厳密な判定が可能です。
●三項演算子を使った判定
数値判定には、もう1つ便利なテクニックがあります。
それが三項演算子です。
三項演算子を使えば、条件分岐をより簡潔に書くことができます。
三項演算子は、次のような構文を持っています。
条件式がtrue
の場合は式1が、false
の場合は式2が評価されます。
この三項演算子を使って、数値の正負判定や0以上の判定を行ってみましょう。
○サンプルコード9:数値の正負判定
まずは、数値が正の数か負の数かを判定する例です。
このsignNumber
関数は、引数num
が0以上の場合は"正の数"
を、そうでない場合は"負の数"
を返します。
三項演算子の条件式には、num >= 0
を指定しています。
num
が0以上の場合は条件式がtrue
になるので、"正の数"
が返されます。
一方、num
が負の数の場合は条件式がfalse
になるので、"負の数"
が返されるわけです。
このように、三項演算子を使えば、条件に応じて異なる値を返すことができます。
○サンプルコード10:0以上の判定
同様に、数値が0以上かどうかを判定する例を見てみましょう。
ここでは、num >= 0
がtrue
の場合はtrue
を、false
の場合はfalse
を返すようにしています。
ただ、実際にはもっと簡潔に書くことができます。
条件式num >= 0
の結果がそのまま真偽値になるので、三項演算子を使う必要がないんですね。
このように、三項演算子は条件分岐を簡潔に書くのに役立ちますが、使いどころを見極めることも大切です。
単純な真偽値の場合は、条件式をそのまま返した方がスッキリしますね。
三項演算子は、条件分岐のコードを短くできる反面、複雑な条件を詰め込みすぎると可読性が下がるというデメリットもあります。
シンプルな条件分岐に使うのが良いでしょう。
また、三項演算子はネストすることもできます。
このgetNumberType
関数では、まずnum
が0かどうかを判定し、0の場合は"ゼロ"
を返します。
0でない場合は、さらにnum
が正の数か負の数かを判定して、それぞれ"正の数"
、"負の数"
を返しています。
三項演算子をネストすれば、このように複数の条件分岐を1行で書くこともできます。
ただし、ネストが深くなると読みづらくなるので、適度な使用にとどめるのが賢明ですね。
三項演算子は、数値判定に限らず、様々な場面で条件分岐を簡潔に書くのに活用できます。
一方で、複雑な条件分岐はif
文で書いた方が読みやすいことも多いです。
状況に応じて、三項演算子とif
文を使い分けていくことが大切だと思います。
●よくあるエラーと対処法
JavaScriptで数値判定を行う際、よく遭遇するエラーがいくつかあります。
これらのエラーは、初心者の方が特につまづきやすいポイントでもあるので、しっかりと理解しておきたいところです。
ここでは、数値判定でよく発生するエラーとその対処法について見ていきましょう。
○文字列を数値に変換できない場合
ユーザー入力値を数値に変換しようとしたときに、変換できない文字列が含まれていると、NaN
(Not a Number)というエラー値が返ってきます。
例えば、次のようなコードを実行すると、NaN
が出力されます。
この場合、文字列"123abc"
には数字以外の文字"abc"
が含まれているため、Number()
関数で数値に変換できません。
NaN
が発生すると、その後の計算処理が正しく行われなくなってしまうので、注意が必要です。
NaN
をチェックするには、isNaN()
関数を使います。
このように、isNaN()
関数でNaN
かどうかを判定し、適切にエラーハンドリングを行うことが大切です。
○NaNの判定と処理
NaN
は、自分自身と等しくない唯一の値であるという特殊な性質を持っています。
そのため、次のような比較は期待通りの結果になりません。
NaN
どうしを比較しても、false
になってしまうのです。
NaN
かどうかを判定するには、先ほども出てきたisNaN()
関数を使うのが確実です。
isNaN()
関数は、引数がNaN
の場合はtrue
を、そうでない場合はfalse
を返します。
数値に変換できない文字列を渡した場合も、true
になります。
ただし、isNaN()
関数は、引数を数値に変換してから判定を行うので、次のような場合はfalse
を返すことに注意しましょう。
真偽値やnull
、空白文字列などは、数値に変換すると0
や0
と等価な値になるため、isNaN()
ではfalse
と判定されます。
厳密にNaN
かどうかを判定したい場合は、Number.isNaN()
関数を使うのが良いでしょう。
Number.isNaN()
関数は、引数がNaN
の場合のみtrue
を返します。
数値に変換できる引数は、すべてfalse
となります。
○Nullと未定義の判定
JavaScriptでは、null
とundefined
は特別な値として扱われます。
この値に対して数値演算を行おうとすると、NaN
や予期しない結果になることがあります。
null
は数値の0
と等価な値として扱われるので、null + 1
は1
になります。
一方、undefined
は数値に変換できないので、undefined + 1
はNaN
になります。
null
やundefined
が数値として使われることを防ぐには、明示的に数値チェックを行うのが良いでしょう。
このisNumberValue()
関数では、引数の型が"number"
であり、かつNaN
でないことを確認しています。
null
とundefined
は、どちらも"number"
型ではないので、false
と判定されます。
●数値判定のベストプラクティス
ここまで、JavaScriptでの数値判定について様々な方法を見てきました。
正規表現や組み込み関数、比較演算子など、数値判定に使える手段は多岐にわたります。
でも、実際にコードを書くときは、どの方法を使うのが最適なのでしょうか?
ここでは、数値判定のベストプラクティスをいくつか紹介しましょう。
○入力値のサニタイズ
ユーザーからの入力値をそのまま信用してはいけません。意図しない値が渡されるかもしれないからです。
数値判定を行う前に、入力値のサニタイズ(無害化)を行うのが賢明でしょう。
例えば、数値に変換する前に、入力値から空白文字を取り除くのは良い習慣です。
このsanitizeInput
関数は、入力値の前後の空白文字を取り除きます。
これにより、" 123 "
のような入力値でも、"123"
に整形されるので、数値変換がスムーズに行えます。
入力値に対して、適切なサニタイズ処理を行うことで、予期しないエラーを防ぐことができるのです。
○例外処理の実装
数値判定の過程では、NaN
やnull
、undefined
など、数値以外の値が現れることがあります。
この値をそのまま計算に使おうとすると、エラーが発生したり、意図しない結果になったりします。
そこで、例外処理を実装して、エラーをキャッチするのが良い方法です。
このparseNumber
関数は、文字列を数値に変換します。
変換できない場合は、throw
文でエラーをスローしています。
try...catch
文を使って、parseNumber
関数を呼び出しています。
エラーが発生した場合は、catch
ブロックでエラーをキャッチし、適切にエラー処理を行います。
このように、例外処理を実装することで、エラーを制御し、アプリケーションをクラッシュから守ることができます。
○可読性の高いコーディング
コードは、自分だけでなく、他の人も読むことを意識して書く必要があります。
可読性の高いコードを書くことで、バグを減らし、メンテナンス性を高められます。
数値判定のコードでも、できるだけ意図が伝わりやすいように書きましょう。
このisValidAge
関数は、年齢の妥当性をチェックします。
年齢が正の整数であること、0歳以上120歳以下の範囲内であることを確認しています。
コメントを適切に入れることで、コードの意図がわかりやすくなっています。
また、条件をわかりやすい変数名に代入することで、コードの読みやすさが増しています。
まとめ
JavaScriptでの数値判定は、Webアプリケーション開発に欠かせないスキルです。
ユーザー入力のバリデーションや計算処理の正確性を確保するために、数値判定の方法を身につけておく必要があります。
常にベストプラクティスを追求し、より良いコードを書くことを意識してください。
一つ一つのコードに責任を持ち、最適な方法を考え抜く姿勢が、優れたエンジニアへの第一歩となるでしょう。
数値判定を確実に行うスキルを身につけることで、より堅牢で信頼性の高いWebアプリケーションを開発できるようになります。
今回学んだ知識を活かし、ユーザー入力のバリデーションや計算処理の実装に挑戦してみてください。