【JavaScript】 数値チェック方法をケース別に解説します
更新日:2021/09/14
JavaScriptでは一言で数値チェックと言っても、その前提条件で意味が異なります。
そのため、初心者が上級者に質問をしにくい問題でもあります。
そこで今回は、JavaScriptでの数値とは何かを含めて、数値チェックの方法をお伝えします。
JavaScriptの数値データ
数値チェックと一言でいっても、その前提条件でチェックする内容が異なります。
数値チェックの方法を解説する前に、知っておいた方がよい、JavaScriptの数値データについて簡単にお伝えしておきます。
JavaScriptには数値として取り扱えるデータ型が複数存在します。
Number型
JavaScriptの数値データは全てNumber型です。
整数型などは存在しません。
(BigInt型がありますが、制限が多いため除外します)
Number型のデータ形式は64ビットのIEEE 754 倍精度浮動小数点数です。
表現できる範囲は二つの定数値で確認できます。
定数 | 値 | |
---|---|---|
最小の正の値 | Number.MIN_VALUE | 5e-324 |
最大の正の値 | Number.MAX_VALUE | 1.7976931348623157e+308 |
上記は正の値なので、負の値は-1を掛け算してください。
なお安全に使用できる範囲として、次の二つの定数が定義されています。
定数 | 値 | |
---|---|---|
最小の整数値 | Number.MIN_SAFE_INTEGER | -9007199254740991 |
最大の整数値 | Number.MAX_SAFE_INTEGER | 90071992547409918 |
こちらの最小値は、負数を含めたものです。
Number.MIN_VALUEとは性質が異なるので注意しましょう。
数値と判断できるString型
JavaScriptの一部の機能では、数値として判断できる文字列を数値として扱うことがあります。
文字列のままで計算できる
console.log( "100" - "1" ); // 99
console.log( 100 - "1" ); // 99
console.log( "100" - 1 ); // 99
console.log( "100" * "1.3" / "2.4" ); // 54.16666666666667
しかし + は文字列の連結を意味するため、加算として使用できません。
文字列で加算はできない
console.log( 100 + 1 ); // 101
console.log( 100 + "1" ); // "1001"
console.log( "100" + 1 ); // "1001"
生成される値が数値のように見えるので、後々まで残る不具合となるケースが多いです。
文字列を数値として扱う場合は、その文字列を受け入れた時点でNumber型に変換しておきましょう。
なお、10進数以外でも数値とみなされます。
10進数以外でも数値とみなすことができる
console.log( "5e-3" -1 ); // -0.995
console.log( "0x0a" -1 ); // 9
null/true/false/Object
nullとfalseは0、trueは1として扱われるケースがあります。
null/true/falseも数値とみなすことができる
console.log( null - 1 ); // -1
console.log( false - 1 ); // -1
console.log( true - 1 ); // 0
またObjectの[Symbol.toPrimitive]プロパティに、数値を返す関数を定義すると、数値として取り扱うことができます。
Objectも数値とみなすことができる
obj = {
[Symbol.toPrimitive]:()=>5
}
console.log( obj + 1 ); // 6
BigInt型
BigInt型はNumber型で表現できない整数を扱うことができます。
BigInt型は最後に n を付けて定義します。
BigInt型の定義と演算
const bigInt = 10000000000n;
console.log( bigInt - 100n ); // 9999999900n
ただし、他の型と演算をおこなうとエラーが発生します。
BigInt型と他の型との演算
console.log( 10000n - 1 ); // TypeError: can't convert BigInt to number
console.log( 10000n - "1" ); // TypeError: can't convert BigInt to number
非常に扱いにくいため、Number型で表現できない整数を扱うとき以外は使用しない方が無難です。
Number型かどうかをチェックする
Number型かどうかのみをチェックする場合、typeof演算子を使用します。
Number型ならtypeof演算子の結果が"number"になります。
Number型かどうかをチェックする関数
const isNumber = n => typeof n === "number";
定数などは用意されていません。
こういうものだと思って、文字列の"number"と比較してください。
次のように、Number型のみtrueを返します。
使用結果
console.log( isNumber( 1000 ) ); // true
console.log( isNumber( "1000" ) ); // false
console.log( isNumber( true ) ); // false
ただしtypeof演算子は、NaN値(数値ではないという意味)と Infinity値(無限大という意味)でも結果が "number"になります。
NaNやInfinityも数値とみなされる
console.log( isNumber( NaN ) ); // true
console.log( isNumber( Infinity ) ); // true
この値を除外したい場合は、Numberオブジェクトの.isFiniteメソッド を使用します。
isFiniteメソッドは、引数がNumber型で有限な値(NaNまたはInfinityでない)のときtrueを返します。
isNumberのような自作関数を作成せずに、直接呼び出します。
NaNやInfinityを除外
console.log( Number.isFinite( 1000 ) ); // true
console.log( Number.isFinite( "1000" ) ); // false
console.log( Number.isFinite( true ) ); // false
console.log( Number.isFinit( NaN ) ); // true
console.log( Number.isFinit( Infinity ) ); // true
整数値かどうかをチェックしたいときは、isIntegerメソッドを使用できます。
こちらもNumber型のみ受け付けます。
整数値かどうかをチェック
console.log( Number.isInteger( 1000 ) ); // true
console.log( Number.isInteger( 1000.1 ) ); // false
console.log( Number.isInteger( true ) ); // false
console.log( Number.isInteger( NaN ) ); // true
console.log( Number.isInteger( Infinity ) ); // true
文字列が数値がどうか確認する
文字列が数値がどうか確認する方法をお伝えします。
isNaN関数によるチェック
文字列が数値かどうかを判定するのは、isNaN関数を使用するのが手っ取り早いです。
isNaN関数は、引数が数値としてみなせないときtrueを返します。
つまり、 !isNaN() がtrueになれば、数値ということになります。
しかしisNaN関数は、数値でないものでも数値とみなします。
(JavaScriptの数値データで挙げているものです)
さらに空文字列("")も数値と判定します。
そこで余計な値が紛れ込まないように、文字列かどうか、および空文字のチェックもおこないます。
文字列が数値かどうかを判定
const isNumberString = n => typeof n === "string" && n !== "" && !isNaN( n );
使用結果は次のようになります。
isNumberStringの使用結果
console.log( isNumberString( "1000" ) ); // true
console.log( isNumberString( "abc" ) ); // false
console.log( isNumberString( "1000abc" ) ); // false
console.log( isNumberString( "" ) ); // false
console.log( isNumberString( 1000 ) ); // false
console.log( isNumberString( true ) ); // false
console.log( isNumberString( null ) ); // false
文字列の中身がない状態をnull値で表すことがあります。
上の結果を見るとfalseになっているので、null値でも問題ないですね。
実際の運用としては、チェックと同時に数値データに変換したほうが都合がよいケースがあります。
この場合は、Number関数で文字列を数値データに変換します。
文字列を数値に変換
const convertStringToNumber = n => {
if( typeof n !== "string" || n === "" ) return false;
const num = Number( n ); // 数値に変換できない場合はNaNが返る
return isNaN( num ) ? false : num;
}
使用結果は次のようになります。
convertStringToNumberの使用結果
console.log( convertStringToNumber( "1000" ) ); // 1000
console.log( convertStringToNumber( "abc" ) ); // false
console.log( convertStringToNumber( "1000abc" ) ); // false
console.log( convertStringToNumber( "" ) ); // false
console.log( convertStringToNumber( 1000 ) ); // false
console.log( convertStringToNumber( true ) ); // false
console.log( convertStringToNumber( null ) ); // false
nullや空文字を0とするときは、if文での判定を変更します。
Number関数はnullと空文字を0に変換してくれるので、次のように変更してみました。
赤文字が変更部分です。
nullと空文字は0に変換
const convertStringToNumber = n => {
if( typeof n !== "string" && n !== null ) return false;
const num = Number( n ); // 数値に変換できない場合はNaNが返る
return isNaN( num ) ? false : num;
}
整数かどうかの確認は、上の関数の結果をNumber.isIntegerメソッドに渡してください。
文字列が整数かどうかの確認
console.log( Number.isInteger( convertNumberString( "1" ) )); // true
console.log( Number.isInteger( convertNumberString( "1.1" ) )); // false
console.log( Number.isInteger( convertNumberString( "abc" ) )); // false
全角数値が混入するケース
文字列に全角数値が混入する場合は、replaceメソッドで全角から半角に変換をしておきます。
全角数値を半角数値に変換
const convertWidhNumber = n =>n.replace( /[0-9]/g,
match=> match[0].codePointAt() - "0".codePointAt()
);
次のように全角と半角の数値が混ざっていても変換できます。
convertWidhNumberの使用例
console.log( convertWidhNumber("0123456789") ); // 0123456789
後は前項の方法で、数値かどうかチェックをしてください。
Number型または数値文字列かをチェックする
Number型でも数値文字列でも、とにかく数値かどうか確認したいときは、これまで紹介してきた二つの方法を組み合わせます。
Number型または数値文字列かをチェック
const isNumberValue = n => {
if( Number.isFinite( n ) ) return true;
return typeof n === "string" && !isNaN( n );
}
いろいろ排除して短くできそうなので、やってみます。
一文にまとめてみる
const isNumberValue = n => Number.isFinite( n ) ? true
: typeof n === "string" && !isNaN( n );
使用結果は次のようになります。
使用結果
console.log( isNumberValue( 1000 ) ); // true
console.log( isNumberValue( "1000" ) ); // true
console.log( isNumberValue( "abc" ) ); // false
console.log( isNumberValue( "1000abc" ) ); // false
console.log( isNumberValue( undefined ) ); // false
console.log( isNumberValue( true ) ); // false
console.log( isNumberValue( null ) ); // false
確認と同時に変換を行いたいときは、次のようになります。
Number型および数値文字列を数値に変換
const convertNumberToValue = n => {
if( Number.isFinite( n ) ) return n;
if( typeof n !== "string") return false;
const num = Number( n );
return isNaN( num ) ? false : num;
}
使用結果は次のようになります。
使用結果
console.log( convertNumberToValue( 1000 ) ); // 1000
console.log( convertNumberToValue( "1000" ) ); // 1000
console.log( convertNumberToValue( "abc" ) ); // false
console.log( convertNumberToValue( "1000abc" ) ); // false
console.log( convertNumberToValue( undefined ) ); // false
console.log( convertNumberToValue( true ) ); // false
console.log( convertNumberToValue( null ) ); // false
ブラウザで入力された数値をチェックする
htmlのinputタグのtype属性に"number"を指定すると、数値を入力することができます。
そのためJavaScript側で取得できる値がNumber型と思ってしまう人もいますが、実際は文字列です。
取得した値が数値かどうかの確認は、文字列が数値がどうか確認するで紹介した方法でおこないます。
(逆に言うと、入力値がNumber型かどうかの確認は必要ありません)
今回は、簡単なデモを作成してみました。
ブラウザで入力された数値をチェック
html
<input id="input-number" type="number">
<button id="check-button">確認</button>
JavaScript
window.addEventListener( "DOMContentLoaded" , ()=> {
const convertStringToNumber = n => {
if( typeof n !== "string" || n === "") return false;
const num = Number( n );
return isNaN( num ) ? false : num;
}
const inputNumber = document.getElementById("input-number");
document.getElementById("check-button").addEventListener("click",
()=>{
const inputValue = inputNumber.value;
const result = convertStringToNumber( inputValue );
alert( result === false ? "数値ではない(" + inputValue + ")" : inputValue );
});
});
inputタグのtype属性に"number"を指定しても、"abc"などの数値以外の文字を入力できます。
その場合、JavaScript側では空文字が取得されます。
空文字の場合0とみなすような処理はできないので注意しましょう。
ブラウザで入力された数値で計算をおこなう場合は、DOMから値を受け取った時点でNumber型に変換してください。
更新日:2021/09/14
関連記事
スポンサーリンク
記事の内容について
こんにちはけーちゃんです。
説明するのって難しいですね。
「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。
裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。
掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。
ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php
このサイトは、リンクフリーです。大歓迎です。