「数値判定」とは何を見分けたいのか
ここでいう「数値判定」は、その値が「本当に“数値として扱っていいものか”どうか」を見分けることです。
JavaScript では、"10" のような文字列も、10 のような number も、"10px" のような文字列も、全部「それっぽく」見えてしまいます。
業務コードでは、次のようなことをよくやります。
const total = price * quantity;
JavaScriptここで price や quantity が「数値ではない」のにそのまま計算すると、NaN(Not a Number)が発生して、
そのままどこかに流れていき、原因が分かりづらいバグになります。
だからこそ、「これは数値として扱っていいか?」を事前にチェックする「数値判定ユーティリティ」が重要になります。
JavaScript の「数値っぽいもの」を整理する
まず、「数値まわりのよくあるパターン」をざっくり整理しておきます。
const a = 10; // number 型(数値)
const b = "10"; // 文字列だが、数値に変換できそう
const c = "10px"; // 数値+単位
const d = "abc"; // 数値に変換できない
const e = NaN; // number 型だが「数値としては壊れている」
JavaScriptここで大事なのは、「NaN も typeof では number になる」という点です。
console.log(typeof 10); // "number"
console.log(typeof NaN); // "number"
JavaScriptつまり、「typeof value === 'number' だけでは“まともな数値かどうか”は分からない」ということです。
「型として number かどうか」と「有効な数値かどうか」を分ける
数値判定を考えるときは、次の二段階に分けると整理しやすくなります。
- 型として
numberかどうか - その
numberがNaNではないかどうか
型として number かどうか
まずは素直に typeof を使います。
function isNumberType(value) {
return typeof value === "number";
}
console.log(isNumberType(10)); // true
console.log(isNumberType("10")); // false
console.log(isNumberType(NaN)); // true(ここがポイント)
console.log(isNumberType(null)); // false
JavaScript「型として number かどうか」を知るだけなら、これで十分です。
ただし、NaN も true になってしまうので、「有効な数値かどうか」を知りたいときはもう一歩踏み込む必要があります。
有効な数値かどうか(NaN を除外する)
NaN かどうかを判定するには、Number.isNaN を使います。
console.log(Number.isNaN(NaN)); // true
console.log(Number.isNaN(10)); // false
console.log(Number.isNaN("abc")); // false
console.log(Number.isNaN(Number("abc"))); // true
JavaScriptこれを組み合わせて、「型が number で、かつ NaN ではない」=「有効な数値」と判定できます。
function isValidNumber(value) {
return typeof value === "number" && !Number.isNaN(value);
}
console.log(isValidNumber(10)); // true
console.log(isValidNumber(NaN)); // false
console.log(isValidNumber("10")); // false
JavaScript業務で「計算に使っていい数値か?」を判定したいときは、この isValidNumber レベルのチェックが欲しくなります。
文字列を「数値として見ていいか」を判定したい場合
実務では、「最初から number 型で来る」ことの方が少なくて、
フォーム入力や API レスポンスなど、「文字列として来る」ケースが多いです。
例えば、"10", "10.5", "0", "abc" などです。
これらを「数値として扱っていいか?」を判定したいときは、いったん Number で変換してから考えます。
function isNumericString(value) {
if (typeof value !== "string") return false;
if (value.trim() === "") return false; // 空文字は数値とみなさない
const n = Number(value);
return !Number.isNaN(n);
}
console.log(isNumericString("10")); // true
console.log(isNumericString("10.5")); // true
console.log(isNumericString(" 20 ")); // true
console.log(isNumericString("")); // false
console.log(isNumericString(" ")); // false
console.log(isNumericString("abc")); // false
console.log(isNumericString("10px")); // false
JavaScriptここで深掘りしたいポイントは三つあります。
一つ目は、「文字列以外は即 false」にしていることです。isNumericString は「文字列が数値として妥当か」を見る関数なので、役割をはっきりさせています。
二つ目は、「空文字や空白だけの文字列は数値とみなさない」と決めていることです。Number("") は 0 になりますが、業務的には「未入力」として扱いたいことが多いので、ここで弾いています。
三つ目は、「Number で変換してから NaN かどうかを見る」という流れです。Number("10px") は NaN になるので、「途中に文字が混ざっているもの」は数値として不適切だと判定できます。
「数値として扱えるか」を総合的に判定するユーティリティ
ここまでの考え方をまとめて、「いろいろな値が来ても“数値として扱えるか”を判定する」関数を作ってみます。
function isNumeric(value) {
if (typeof value === "number") {
return !Number.isNaN(value);
}
if (typeof value === "string") {
if (value.trim() === "") return false;
const n = Number(value);
return !Number.isNaN(n);
}
return false;
}
console.log(isNumeric(10)); // true
console.log(isNumeric(NaN)); // false
console.log(isNumeric("10")); // true
console.log(isNumeric("10.5")); // true
console.log(isNumeric("")); // false
console.log(isNumeric("abc")); // false
console.log(isNumeric("10px")); // false
console.log(isNumeric(null)); // false
console.log(isNumeric(undefined)); // false
JavaScriptこの isNumeric は、「number 型の有効な数値」か「数値に変換可能な文字列」だけを true にします。
業務で「この値を数値として扱ってよいか?」をざっくり判定したいときに、とても使いやすい形です。
数値判定と「バリデーション」「変換」をどう分けるか
実務でよくある失敗が、「数値判定」「変換」「業務ルールのチェック」をごちゃ混ぜにしてしまうことです。
例えば、こんなコードです。
const n = Number(input);
if (!n) {
console.log("不正な値");
}
JavaScriptこのコードは、0 や NaN、""、null などを全部「不正」とみなしてしまいます。
「0 は有効な値なのに弾かれてしまう」という典型的なバグです。
よりよい考え方は、段階を分けることです。
- 「数値として解釈できるか?」(数値判定+変換)
- 「業務ルールとして妥当か?」(範囲チェックなど)
const n = isNumeric(input) ? Number(input) : null;
if (n === null) {
console.log("数値として解釈できません");
} else if (n < 0) {
console.log("0 以上を入力してください");
} else {
console.log("OK:", n);
}
JavaScriptこのように、「数値として扱えるか」と「業務的に許可するか」を分けて書くと、
コードの意図がはっきりし、バグの原因も追いやすくなります。
実務での具体的な利用イメージ
フォーム入力のチェック
数量や金額などをフォームで入力させるケースを考えます。
const raw = {
quantity: "3",
unitPrice: "1200",
};
if (!isNumeric(raw.quantity)) {
console.log("数量が数値ではありません");
} else if (!isNumeric(raw.unitPrice)) {
console.log("単価が数値ではありません");
} else {
const quantity = Number(raw.quantity);
const unitPrice = Number(raw.unitPrice);
const total = quantity * unitPrice;
console.log("合計金額:", total);
}
JavaScriptここでは、「数値として扱えるか?」を isNumeric で判定し、
そのあとで Number で変換して計算しています。
CSV や外部データの取り込み
CSV や外部システムからのデータは、基本的に全部文字列です。
その中から「数値として扱えるものだけを抽出したい」ときにも、数値判定ユーティリティが役立ちます。
const rows = ["10", "20", "abc", "30"];
const numbers = rows
.filter(isNumeric)
.map((v) => Number(v));
console.log(numbers); // [10, 20, 30]
JavaScriptこのように、「判定」と「変換」を組み合わせることで、
「壊れたデータを静かに混ぜてしまう」リスクを減らせます。
小さな練習で感覚をつかむ
最後に、手を動かして慣れるためのミニ課題を提案します。
自分で isNumberType, isValidNumber, isNumericString, isNumeric を実装して、次の値を片っ端から試してみてください。
10, 0, -1, NaN, "10", "10.5", " 20 ", "abc", "10px", "", " ", null, undefined
それぞれに対して、「どの関数が true を返すか」「どこで false になるか」をコンソールに出してみると、
「型としての number」と「有効な数値」と「数値に変換可能な文字列」が、頭の中でちゃんと分かれてきます。
そこまで行けたら、もう数値判定は実務レベルです。
あとは、自分のプロジェクトの要件に合わせて、「どこまでを許容するか」を微調整していけば OK です。
