●JavaScriptで数値を判定するとは
JavaScriptを使った開発業務に携わり始めたばかりの若手エンジニアの皆さん、数値判定で悩んだことはありませんか?
正確に数値を判定することは、バグの少ないコードを書くために欠かせないスキルです。
○数値判定が必要な場面
ユーザー入力値のバリデーションや、APIレスポンスのデータ型チェックなど、数値を扱うシーンは多岐にわたります。
例えば、年齢入力フォームで数字以外の値が入力された場合、エラーメッセージを表示する必要がありますよね。
こんな時、数値判定の知識があれば、簡単に対処できます。
○判定方法の概要
数値判定の方法は、大きく分けて次の4つがあります。
- 型を使った判定
- 数値メソッドを使った判定
- 正規表現を使った判定
- parseFloatとisFiniteの組み合わせ
この方法を使い分けることで、様々な場面で数値判定を行うことができます。
これから、それぞれの方法を詳しく見ていきましょう。
きっと、数値判定のスキルが身につくはずです。
●型を使った数値判定
JavaScriptで数値を判定する方法の1つに、型を使った判定があります。
型判定では、変数のデータ型を調べることで、その値が数値かどうかを判断します。
○サンプルコード1:typeof演算子
typeof演算子は、変数のデータ型を文字列で返してくれる便利な演算子です。
数値の場合は、”number”という文字列が返ってきます。
上記のコードでは、numは数値型、strは文字列型であることがわかります。
typeof演算子を使えば、簡単に変数のデータ型をチェックできますね。
ただ、typeof演算子にはちょっとした落とし穴があります。
それは、NaNに対してもtypeof演算子は”number”を返すということです。
NaNは、Not a Numberの略で、数値ではないことを表す特殊な値です。
しかし、typeof演算子ではNaNを数値型と判定してしまうので、注意が必要ですね。
NaNについては、後ほど詳しく説明します。
○サンプルコード2:constructorプロパティ
もう1つの型判定の方法は、constructorプロパティを使う方法です。
constructorプロパティは、そのオブジェクトのコンストラクタ関数を参照します。
上記のコードでは、numのコンストラクタ関数はNumber、strのコンストラクタ関数はStringであることを確認しています。
この方法なら、NaNも正しく判定できます。
ただ、constructorプロパティを使った判定は、typeof演算子に比べると少し冗長な書き方になってしまいます。
状況に応じて、適切な方法を選ぶことが大切ですね。
●数値メソッドを使った判定
JavaScriptには、数値かどうかを判定するための便利なメソッドがいくつか用意されています。
これらのメソッドを使えば、型判定よりも簡潔に数値判定を行うことができます。
○サンプルコード3:isNaN()
isNaN()は、与えられた値がNaNかどうかを判定するメソッドです。
NaNは、数値ではないことを表す特殊な値ですが、typeof演算子では数値型と判定されてしまいます。
そんな時は、isNaN()を使ってNaNかどうかを確認しましょう。
上記のコードでは、数値の42はfalse、文字列の”42″もfalseになっています。
一方、文字列の”hello”とNaNはtrueになりますね。つまり、isNaN()は数値に変換できない値に対してtrueを返すのです。
ただ、isNaN()にはちょっとした落とし穴があります。
それは、文字列の”42″のように、数値に変換できる文字列に対してもfalseを返すということです。
これでは、文字列が混ざった値をきちんと判定できません。
○サンプルコード4:Number.isNaN()
そこで登場するのが、Number.isNaN()です。
これは、isNaN()の問題点を改良したメソッドで、より厳密にNaNかどうかを判定してくれます。
Number.isNaN()は、NaNに対してのみtrueを返し、他の値に対してはすべてfalseを返します。
これなら、文字列が混ざった値も正しく判定できますね。
○サンプルコード5:isFinite()
isFinite()は、与えられた値が有限数かどうかを判定するメソッドです。
有限数とは、無限大ではない数値のことを指します。
上記のコードでは、数値の42と文字列の”42″はtrue、文字列の”hello”とInfinity、NaNはfalseになっています。
isFinite()は、数値に変換できる値に対してtrueを返し、数値に変換できない値や無限大に対してはfalseを返すのです。
●正規表現を使った数値判定
JavaScriptの数値判定には、正規表現を使う方法もあります。
正規表現を使えば、文字列のパターンを柔軟にマッチングできるので、より細かな条件で数値を判定できます。
○サンプルコード6:単純な数値パターン
まずは、単純な数値のパターンを正規表現で表現してみましょう。
数字だけで構成される文字列を判定するには、次のような正規表現を使います。
この正規表現では、^
は文字列の先頭、\d+
は1つ以上の数字、$
は文字列の末尾を表しています。
つまり、先頭から末尾まで数字だけで構成される文字列にマッチするのです。
上記のコードでは、”42″はパターンにマッチするのでtrue、”42.5″と”hello”はマッチしないのでfalseになります。
ただ、この正規表現では小数点や符号を含む数値は判定できません。
○サンプルコード7:小数や符号も考慮したパターン
小数点や符号を含む数値を判定するには、正規表現をもう少し複雑にする必要があります。
次のような正規表現を使ってみましょう。
この正規表現では、[-+]?
は符号が0個または1個、\d+
は1つ以上の数字、(\.\d+)?
は小数点とその後の数字が0個または1個を表しています。
つまり、符号と整数部は必須で、小数部は任意という条件になります。
上記のコードでは、”42″、”-42″、”+42″、”42.5″はパターンにマッチするのでtrue、”hello”はマッチしないのでfalseになります。
この正規表現なら、多くの数値形式を判定できますね。
●parseFloatとisFiniteの組み合わせ
JavaScriptの数値判定には、parseFloatとisFiniteを組み合わせる方法もあります。
parseFloatは文字列を浮動小数点数に変換し、isFiniteは変換結果が有限数かどうかを判定します。
○サンプルコード8:文字列から数値への変換と判定
parseFloatとisFiniteを使った数値判定の例を見てみましょう。
この例では、isNumber関数の中でparseFloatとisFiniteを組み合わせています。
parseFloatで文字列を数値に変換し、その結果をisFiniteで判定しているのです。
上記のコードでは、”42″、”-42″、”42.5″はtrueになり、”hello”と空文字列””はfalseになります。
この方法なら、数値形式の文字列を正しく判定できますね。
ただ、parseFloatとisFiniteの組み合わせにはちょっとした落とし穴があります。
それは、文字列の先頭が数値で始まる場合、parseFloatが数値部分だけを取り出してしまうということです。
上記のコードでは、”42px”はtrueになります。
これは、parseFloatが”42px”の先頭にある数値部分”42″だけを取り出し、isFiniteがそれを有限数と判定するためです。
一方、”hello42″はfalseになります。
parseFloatとisFiniteの組み合わせは、数値形式の文字列を判定するのに便利な方法です。
でも、文字列の先頭が数値で始まる場合の挙動には注意が必要ですね。
●NaNについて理解する
NaNという値に悩まされたことはありませんか?
数値判定を行う際、NaNは厄介な存在ですよね。
○NaNとは何か
NaNは「Not a Number」の略で、数値ではないことを表す特殊な値です。
例えば、数値として解釈できない計算を行った場合、その結果はNaNになります。
上記のコードでは、負の数の平方根、0を0で割る計算、数値に変換できない文字列をparseIntで変換しようとした場合、すべてNaNになっています。
NaNは数値ではありませんが、typeof演算子ではnumberと判定されてしまいます。
これは、NaNが数値型に分類されているためです。
また、NaNは自分自身と等しくない唯一の値です。これは、NaNを判定する際に役立ちます。
○サンプルコード9:NaNの判定
NaNを判定するには、isNaN関数を使う方法が一般的です。
上記のコードでは、NaNと数値に変換できない文字列”hello”に対してisNaNはtrueを返し、数値の42に対してはfalseを返しています。
ただ、isNaN関数は、渡された値を数値に変換できるかどうかを判定するため、数値に変換できる文字列に対してもfalseを返してしまいます。
より厳密にNaNを判定するには、Number.isNaN関数を使います。
Number.isNaN関数は、渡された値がNaNかどうかを判定します。
NaNに対してのみtrueを返し、他の値に対してはすべてfalseを返すのです。
●数値判定のよくあるエラーと対処法
JavaScriptを使った開発業務で数値判定を行う際、思わぬエラーに遭遇することがありますよね。
ここでは、数値判定でよく見られるエラーとその対処法について見ていきましょう。
○”0″と0の混同
文字列の”0″と数値の0を混同することがよくあるエラーの1つです。
例えば、ユーザー入力値が文字列で渡されてくる場合、”0″と0を同じように扱ってしまうと、意図しない結果になることがあります。
上記のコードでは、ユーザー入力値が文字列の”0″であるにもかかわらず、”ユーザーは0以外を入力しました”と表示されてしまいます。
これは、===演算子が型の違いを厳密にチェックするためです。
この問題を解決するには、比較する前に文字列を数値に変換するか、==演算子を使って型の違いを無視して比較する必要があります。
上記のコードでは、Number関数を使ってuserInputを数値に変換してから比較しています。
これで、”ユーザーは0を入力しました”と正しく表示されます。
○ブール値やnullとの混同
ブール値やnullを数値と混同することもエラーの原因になります。
例えば、次のようなコードを見てみましょう。
上記のコードでは、”isValidは1です”と表示されます。
これは、==演算子が型の違いを無視して比較するためです。trueは数値の1に、falseは数値の0に変換されるのです。
同様に、nullも数値の0と混同されがちです。
上記のコードでは、”valueは0です”と表示されます。
nullは数値の0に変換されるため、==演算子では等しいと判定されるのです。
これらの問題を解決するには、===演算子を使って型の違いを厳密にチェックするのが良いでしょう。
上記のコードでは、いずれも”isValidは1ではありません”と”valueは0ではありません”が表示されます。
===演算子を使うことで、型の違いを正しく判定できるのです。
●数値判定の応用例
JavaScriptでの数値判定は、様々な場面で役立ちます。
ここでは、数値判定の応用例として、ユーザー入力値の検証と、数値判定を使ったバリデーションについて見ていきましょう。
○サンプルコード10:ユーザー入力値の検証
ユーザー入力値の検証は、数値判定の代表的な応用例です。
例えば、年齢入力フォームで数値以外の値が入力された場合、エラーメッセージを表示する必要がありますよね。
上記のコードでは、validateAge関数で年齢の検証を行っています。
入力値をNumber関数で数値に変換し、isNaNで数値かどうかを判定しています。
また、年齢の有効範囲(0以上120以下)もチェックしています。
数値以外の値や、有効範囲外の値が入力された場合は、”有効な年齢を入力してください”というエラーメッセージを表示します。
有効な年齢が入力された場合は、”入力された年齢は ○○ です”というメッセージを表示します。
このように、数値判定を使ってユーザー入力値の検証を行うことで、不正な入力を防ぎ、アプリケーションの信頼性を高めることができます。
○数値判定を使ったバリデーション
数値判定は、バリデーションの重要な要素です。
バリデーションとは、データの妥当性を確認するプロセスのことで、ユーザー入力値の検証もその一部です。
数値判定を使ったバリデーションの例として、次のようなものが挙げられます。
- 数量入力フォームで、負の数や小数が入力されていないかチェックする
- 金額入力フォームで、数値以外の値が入力されていないかチェックする
- 日付入力フォームで、数値以外の値や、存在しない日付が入力されていないかチェックする
これらのバリデーションでは、数値判定メソッドや正規表現を使って、入力値が期待する形式であるかどうかを確認します。
数値判定を適切に行うことで、データの整合性を保ち、アプリケーションの信頼性を高めることができるのです。
例えば、数量入力フォームのバリデーションでは、次のようなコードを使うことができます。
上記のコードでは、validateQuantity関数で数量の検証を行っています。
isNaNで数値かどうかを判定し、0未満でないかチェックしています。
また、Number.isIntegerで整数かどうかも確認しています。
まとめ
JavaScriptでの数値判定は、型判定、数値メソッド、正規表現、parseFloatとisFiniteの組み合わせなど、様々な方法があることがわかりました。
それぞれの方法には長所と短所がありますが、状況に応じて適切な方法を選ぶことが大切ですね。
また、数値判定でよく見られるエラーとその対処法を理解することで、バグの少ないコードを書けるようになります。
数値判定のスキルを磨いて、ユーザー入力値の検証やバリデーションなどに活用していきましょう。
JavaScriptでの数値判定に自信を持ち、開発業務を進められるようになることを目指して、これからも学びを深めていきましょう。