JavaScriptで数値をパースする方法
フォームフィールド、URLパラメータ、またはJSON APIレスポンスから値を読み取る場合、ほぼ常に文字列として取得されます。数値を使った計算を行う前に、それを数値に変換する必要があります。JavaScriptには複数の変換方法がありますが、それぞれの動作が十分に異なるため、誤った方法を選択すると微妙なバグの原因となります。この記事では、主な変換メソッド、それぞれをいつ使用すべきか、そして開発者が最も頻繁につまずくエッジケースについて説明します。
重要なポイント
parseInt()とparseFloat()は部分的なパースを実行し、左から右へ読み取って最初の無効な文字で停止します —"24px"のような文字列に便利です。Number()と単項+演算子は、文字列全体が有効である必要があり、そうでない場合はNaNを返します — APIデータからの厳密な変換に最適です。- 常に
parseInt()に基数(radix)を渡し、常にNumber.isNaN()でグローバルなisNaN()ではなく結果を検証してください。 Number.MAX_SAFE_INTEGERを超える整数にはBigInt()を使用し、パース前にロケール形式の文字列を正規化してください。
クイック比較:JavaScriptの文字列から数値への変換メソッド
| メソッド | 入力 "42px" | 入力 "3.14" | 入力 "" | 入力 "abc" |
|---|---|---|---|---|
parseInt("42px", 10) | 42 | 3 | NaN | NaN |
parseFloat("42px") | 42 | 3.14 | NaN | NaN |
Number("42px") | NaN | 3.14 | 0 | NaN |
+"42px" | NaN | 3.14 | 0 | NaN |
parseInt():整数の部分的パース
parseInt(string, radix)は、文字を左から右へ読み取り、パースできない文字に遭遇した瞬間に停止します。これにより、"24px"や"10rem"のような、数値が最初に来る文字列に便利です。
parseInt("24px", 10) // 24
parseInt("3.99", 10) // 3 (小数点でパースが停止)
parseInt("abc", 10) // NaN (最初の文字が無効)
常に基数を渡してください。 基数を指定しないと、parseIntは0xで始まる文字列を16進数として扱い、それ以外は10進数でパースします。最近のエンジンはデフォルトで10進数ですが、基数を省略することはよく知られたバグの原因であり、意図が不明確になります。
parseInt("0xFF", 16) // 255 — 明示的な16進数パース
parseInt("011", 10) // 11 — 基数により曖昧さを防ぐ
あまり知られていない動作: parseIntは"6.022e23"の小数点で停止するため、parseInt("6.022e23", 10)は602200000000000000000000ではなく6を返します。大きな浮動小数点数を切り捨てるためにparseIntを使用しないでください。代わりにMath.trunc()を使用してください。
parseFloat():小数の部分的パース
parseFloat()はparseIntと同じように動作しますが、小数部分を保持します。基数パラメータはなく、常に10進数でパースします。
parseFloat("3.14rem") // 3.14
parseFloat("1e3") // 1000 — 科学的記数法を理解
parseFloat("px10") // NaN — 最初の文字が無効
入力に小数値が含まれる可能性があり、それを保持したい場合はparseFloatを使用してください。
Number()と単項+:厳密な変換
Number()と単項+演算子の両方とも、文字列全体が有効な数値である必要があります。一部でも無効な場合はNaNを取得します。この厳密性は、APIレスポンスや検証済みフォームデータを扱う場合に利点となります。部分的なパースはサイレントエラーになる可能性があります。
Number("42") // 42
Number("3.14") // 3.14
Number("42px") // NaN — parseIntより厳密
Number("") // 0 — これに注意
+"42" // 42 — 同一の動作、短い構文
空文字列のエッジケースはフォーム処理で重要です。Number("")はNaNではなく0を返すため、欠落値をマスクする可能性があります。変換前に常に空の入力をチェックしてください。
Discover how at OpenReplay.com.
数値セパレータは実行時に機能しない
JavaScriptのソースコードでは1_000_000を数値リテラルとして使用できますが、この構文は文字列パースには引き継がれません。
parseInt("1_000", 10) // 1 — アンダースコアでパースが停止
Number("1_000") // NaN
APIやユーザー入力が千の位の区切り文字としてアンダースコアを使用している場合は、str.replace(/_/g, "")で最初に削除してください。
BigInt():大きな整数のパース
JavaScriptのNumber型はNumber.MAX_SAFE_INTEGER(2⁵³ − 1)を超えると精度を失います。それを超える値 — データベースID、暗号値、金融整数 — にはBigInt()を使用してください。
BigInt("9007199254740993") // 9007199254740993n — 正確
Number("9007199254740993") // 9007199254740992 — 1つずれている
文字列を直接BigInt()に渡してください。最初にparseIntを通さないでください。その時点で精度が既に失われているためです。BigInt値は明示的な変換なしに通常のNumber値と算術演算で混在できないことに注意してください。
ロケール対応のパース
JavaScriptには、"1.234,56"(ドイツ語やスペイン語のロケールで一般的)のようなロケール形式の数値をパースする組み込み関数はありません。パース前に文字列を手動で正規化する必要があります:
const raw = "1.234,56"
const normalized = raw.replace(/\./g, "").replace(",", ".")
parseFloat(normalized) // 1234.56
どのメソッドを使用すべきか?
- ユーザー入力または単位付きのCSS値 →
parseInt(str, 10)またはparseFloat() - APIレスポンスまたは厳密に検証されたデータ →
Number()または単項+ - 2⁵³ − 1を超える整数 →
BigInt() - 常に使用前に結果が
NaNでないことを検証してください:
const qty = parseInt(input, 10)
if (Number.isNaN(qty)) {
// 無効な入力を処理
}
グローバルなisNaN()ではなくNumber.isNaN()を使用してください。グローバル版は最初に引数を強制変換するため、isNaN("")は""が数値でないにもかかわらずfalseを返します。
結論
適切なJavaScriptの数値パースメソッドは、入力について何を知っているかによって異なります。部分的なパースが許容され期待される場合はparseIntまたはparseFloatを使用してください。文字列全体が有効な数値である必要がある場合はNumber()または単項+を使用してください。大きな整数で精度が重要な場合はBigInt()を使用してください。すべての場合において、結果を使用する前にNaNをチェックしてください。
よくある質問
parseIntは文字列を左から右へ読み取り、整数の一部として解釈できない最初の文字で停止します。Numberは文字列全体が有効な数値である必要があります。例えば、42pxのparseIntは42を返しますが、42pxのNumberはNaNを返します。部分的なパースにはparseIntを、厳密な変換にはNumberを使用してください。
ECMAScript仕様では、空文字列をNumberまたは単項プラス演算子に渡すと0に変換されると定義されています。これは欠落したフォーム値をマスクする可能性があります。空白フィールドをゼロとして扱うことを避けるため、数値に変換する前に常に入力文字列が空かどうかをチェックしてください。
整数がNumber.MAX_SAFE_INTEGERを超える場合、つまり2の53乗マイナス1を超える場合にBigIntを使用してください。そのしきい値を超えると、Numberは精度を失い、値を静かに丸める可能性があります。中間ステップで精度が失われるため、parseIntやNumberを通して変換するのではなく、数値文字列を直接BigIntに渡してください。
グローバルなisNaNはチェック前に引数を数値に強制変換するため、誤解を招く結果を生成します。例えば、空文字列のisNaNは、空文字列が0に強制変換されるためfalseを返します。Number.isNaNは強制変換をスキップし、値が文字通りNaNの場合にのみtrueを返すため、検証に信頼できる選択肢となります。
Complete picture for complete understanding
Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.
Check our GitHub repo and join the thousands of developers in our community.