JavaScript Tips | 基本・共通ユーティリティ:基本判定・変換 – 数値変換

JavaScript JavaScript
スポンサーリンク

「数値変換」とは何をするものか

数値変換は、「文字列やその他の値を、最終的に“ちゃんとした数値”として扱える形にする」ことです。
業務コードでは、フォーム入力、CSV、API のレスポンスなど、ほとんどが「文字列」でやってきますが、計算や比較をするには数値に変換しないといけません。

例えば、ユーザーが「10」と入力したとき、それは "10" という文字列です。
そのままでは足し算しても "10" + 5 === "105" になってしまうので、「10 という数値」に変換する必要があります。

const input = "10";

console.log(input + 5);        // "105"(文字列結合)
console.log(Number(input) + 5); // 15(数値として計算)
JavaScript

この「どのように数値に変換するか」をきちんと設計しておかないと、業務ロジックが静かに壊れます。


JavaScript の基本的な数値変換パターン

Number 関数による変換

一番素直な変換は Number(value) です。
「その値を“数値として解釈できるか”」を試し、ダメなら NaN(Not a Number)になります。

console.log(Number("10"));      // 10
console.log(Number("10.5"));    // 10.5
console.log(Number(""));        // 0
console.log(Number("  20 "));   // 20
console.log(Number("abc"));     // NaN
console.log(Number(null));      // 0
console.log(Number(undefined)); // NaN
JavaScript

ここで重要なのは、「""null が 0 になる」「undefined や意味不明な文字列は NaN になる」という挙動です。
業務的に「空文字を 0 とみなしてよいのか?」「null を 0 にしてよいのか?」は、要件によって変わります。

そのため、Number をそのまま使うのではなく、「自分たちのルールを包んだユーティリティ関数」を用意するのが実務的です。

parseInt / parseFloat の特徴

parseIntparseFloat は、「文字列の先頭から読めるところまで数値として読む」関数です。

console.log(parseInt("10", 10));      // 10
console.log(parseInt("10px", 10));    // 10
console.log(parseInt("px10", 10));    // NaN

console.log(parseFloat("10.5"));      // 10.5
console.log(parseFloat("10.5kg"));    // 10.5
console.log(parseFloat("kg10.5"));    // NaN
JavaScript

Number("10px") は NaN ですが、parseInt("10px", 10) は 10 になります。
「単位付きの文字列から数値部分だけ取りたい」ようなケースでは便利ですが、「中途半端な文字列も通してしまう」ので、バリデーションとしてはやや甘いです。


NaN をどう扱うかが数値変換の肝

数値変換で一番危険なのは、「変換に失敗して NaN になったのに、そのまま計算に使ってしまう」ことです。

const value = Number("abc");  // NaN

console.log(value + 10);      // NaN
console.log(value > 0);       // false
console.log(value < 0);       // false
console.log(value === NaN);   // false(ここも罠)
JavaScript

NaN は「何と比較しても false」「自分自身とすら等しくない」という特殊な値です。
NaN かどうかを判定したいときは、Number.isNaN(value) を使います。

console.log(Number.isNaN(NaN));        // true
console.log(Number.isNaN("abc"));      // false
console.log(Number.isNaN(Number("abc"))); // true
JavaScript

業務コードでは、「数値変換に失敗したらどうするか?」を必ず決めておく必要があります。
例えば、「エラーとして扱う」「0 に丸める」「null にする」などです。


業務で使える toNumber ユーティリティの設計

ここからが本番です。
実務で使える「数値変換ユーティリティ」をどう設計するかを、初心者向けにかみ砕いて考えてみます。

シンプルな toNumber(失敗したら NaN のまま)

まずは、「Number をラップして、変換の入り口を統一する」パターンです。

function toNumber(value) {
  return Number(value);
}

console.log(toNumber("10"));      // 10
console.log(toNumber("10.5"));    // 10.5
console.log(toNumber(""));        // 0
console.log(toNumber("abc"));     // NaN
JavaScript

これだけでも、「プロジェクト内で数値変換は必ず toNumber を通す」というルールにしておけば、
あとから「空文字を 0 にするのはやめたい」となったときに、toNumber の中身だけを変えれば済みます。

失敗時にデフォルト値を返す toNumberOr

「NaN のままだと扱いづらいので、失敗したらデフォルト値を返したい」という場面も多いです。

function toNumberOr(value, defaultValue) {
  const n = Number(value);
  return Number.isNaN(n) ? defaultValue : n;
}

console.log(toNumberOr("10", 0));     // 10
console.log(toNumberOr("abc", 0));    // 0
console.log(toNumberOr("", 0));       // 0(ここをどうするかは要件次第)
JavaScript

ここでのポイントは、「NaN かどうかを必ずチェックしている」ことです。
Number(value) をそのまま返すのではなく、「失敗したらどうするか」をユーティリティの中で決めています。

空文字や null をどう扱うかを決める

業務では、「空文字や null は“未入力”として扱いたいので、0 にはしたくない」という要件もよくあります。
その場合は、もう一段ルールを足します。

function toNumberOrNull(value) {
  if (value === null || value === undefined) return null;
  if (typeof value === "string" && value.trim() === "") return null;

  const n = Number(value);
  return Number.isNaN(n) ? null : n;
}

console.log(toNumberOrNull("10"));     // 10
console.log(toNumberOrNull(""));       // null
console.log(toNumberOrNull("  "));     // null
console.log(toNumberOrNull(null));     // null
console.log(toNumberOrNull("abc"));    // null
JavaScript

こうしておくと、「数値として解釈できないものは全部 null にする」というルールが明確になります。
あとは、「null のときにどう扱うか」を別の層で決めればよくなります。


整数専用の変換 toInt の考え方

金額や個数など、「小数点以下はいらない」「整数として扱いたい」ケースも多いです。
その場合は、parseIntMath.floor ではなく、「整数として妥当かどうか」をチェックしたうえで変換するのが安全です。

function toIntOrNull(value) {
  if (value === null || value === undefined) return null;
  if (typeof value === "string" && value.trim() === "") return null;

  const n = Number(value);
  if (!Number.isInteger(n)) return null;
  return n;
}

console.log(toIntOrNull("10"));     // 10
console.log(toIntOrNull("10.5"));   // null
console.log(toIntOrNull("abc"));    // null
console.log(toIntOrNull(""));       // null
JavaScript

「10.5 を 10 に丸める」のか「エラー扱いにする」のかは、業務要件次第です。
上の例では、「整数としておかしいものは null にする」という、わりと厳しめのルールにしています。


入力値のバリデーションと数値変換の分離

実務でよくある失敗が、「バリデーションと変換をごちゃ混ぜにしてしまう」ことです。
例えば、次のようなコードです。

const value = Number(input);

if (!value) {
  console.log("不正な値");
}
JavaScript

このコードは、0NaN""null などを全部「不正」とみなしてしまいます。
「0 は有効な値なのに弾かれてしまう」という典型的なバグです。

よりよい書き方は、「まず変換」「次に妥当性チェック」と段階を分けることです。

const value = toNumberOrNull(input);

if (value === null) {
  console.log("数値として解釈できません");
} else if (value < 0) {
  console.log("0 以上を入力してください");
} else {
  console.log("OK:", value);
}
JavaScript

このように、「変換」と「業務ルールとしてのチェック」を分けて書くと、コードの意図がはっきりします。


実務での具体的な利用イメージ

例えば、フォームから「数量」と「単価」が文字列で送られてくるケースを考えます。

const raw = {
  quantity: "3",
  unitPrice: "1200",
};

const quantity = toIntOrNull(raw.quantity);
const unitPrice = toNumberOrNull(raw.unitPrice);

if (quantity === null || unitPrice === null) {
  console.log("数量または単価が不正です");
} else {
  const total = quantity * unitPrice;
  console.log("合計金額:", total);
}
JavaScript

ここでは、「文字列をそのまま計算に使わない」「変換に失敗したら null にして、そこで止める」という方針を徹底しています。
こうしておくと、「’abc’ * ’10’ が NaN になって、そのままどこかに流れていく」といった事故を防げます。


小さな練習で感覚をつかむ

最後に、理解を定着させるための練習を提案します。
toNumberOr, toNumberOrNull, toIntOrNull を自分で実装して、次のような値を片っ端から渡してみてください。

"10", "10.5", " 20 ", "abc", "", " ", null, undefined, 0, -1, "0", "001", "1e3" などです。

その結果をコンソールに出しながら、「このプロジェクトなら、どの値を許容して、どの値を弾くべきか?」を自分なりに言語化してみると、
「なんとなく Number を呼ぶ」から「意図を持って数値変換する」へ、一段レベルアップできます。

タイトルとURLをコピーしました