最終更新: 2026年2月 | ES2024 (ECMAScript 2024) 対応
JavaScriptで文字列を数値(整数・小数点数)に変換する方法を、現役のエンジニアが徹底解説します。Number(), parseInt(), parseFloat(), 単項プラス演算子の違い、型強制、厳密な変換まで完全網羅。
1. なぜ文字列を数値に変換する必要があるのか
よくあるシーン
// フォーム入力値(常に文字列)
const age = document.getElementById('age').value; // "25" (文字列)
// 計算に使いたい
const nextYear = age + 1; // "251" (文字列結合!)問題点:
- 意図しない文字列結合
- 予期しない動作
- バグの温床
解決策:
明示的に型変換する
const age = Number(document.getElementById('age').value); // 25 (数値)
const nextYear = age + 1; // 26実務での使用例
1. API レスポンスの処理
// JSON から取得した値(文字列の場合がある)
const response = await fetch('/api/product');
const data = await response.json();
const total = Number(data.price) * Number(data.quantity);
// 1980 * 5 = 99002. URL パラメータの処理
// URLSearchParams は常に文字列を返す
const params = new URLSearchParams(window.location.search);
const page = Number(params.get('page')) || 1; // "2" → 2
const limit = Number(params.get('limit')) || 10;3. ローカルストレージの処理
// localStorage は常に文字列で保存
const savedCount = localStorage.getItem('count');
const count = Number(savedCount) || 0; // "5" → 52. 整数への変換方法
2-1. parseInt() 関数(推奨)
const str = "123";
const num = parseInt(str);
console.log(num); // 123
console.log(typeof num); // "number"特徴:
- ✅ 整数のみに変換
- ✅ 基数指定が可能(2進数、16進数など)
- ✅ 先頭の数値のみ抽出
- ❌ 小数点以下は切り捨て
基数指定(重要!)
// 10進数(デフォルト)
parseInt("123"); // 123
parseInt("123", 10); // 123(明示的に推奨)
// 2進数
parseInt("1010", 2); // 10
// 8進数
parseInt("12", 8); // 10
// 16進数
parseInt("A", 16); // 10
parseInt("FF", 16); // 255
parseInt("0xFF", 16); // 255⚠️ 重要な注意点:
// 基数を省略すると予期しない動作
parseInt("08"); // 8(現代のJSでは10進数)
parseInt("08", 10); // 8(推奨: 明示的に10進数指定)
// 古いブラウザでは8進数と解釈される場合があった
// 常に基数を指定する習慣をつける先頭の数値を抽出
parseInt("123abc"); // 123
parseInt("123.45"); // 123(小数点以下は無視)
parseInt(" 456 "); // 456(前後の空白は無視)
parseInt("789px"); // 789
// 先頭が数字でない場合
parseInt("abc123"); // NaN
parseInt(""); // NaN2-2. Math.floor() / Math.ceil() / Math.round()
const str = "123.45";
// 切り捨て
Math.floor(Number(str)); // 123
Math.floor(123.99); // 123
// 切り上げ
Math.ceil(Number(str)); // 124
Math.ceil(123.01); // 124
// 四捨五入
Math.round(Number(str)); // 123
Math.round(123.5); // 124
Math.round(123.4); // 1232-3. ビット演算(トリッキー)
const str = "123.45";
// ダブルチルダ(~~)
~~str; // 123
~~"123.99"; // 123
// ビットOR(|)
str | 0; // 123
"123.99" | 0; // 123
// ビットシフト(>>)
str >> 0; // 123⚠️ 注意:
- 32ビット整数の範囲内のみ(-2,147,483,648 ~ 2,147,483,647)
- 範囲外は予期しない結果
- 可読性が低い(コードレビューで嫌われる)
// 範囲外の例
~~2147483648; // -2147483648(オーバーフロー)
2147483648 | 0; // -2147483648
// 推奨しない
parseInt("123"); // ✅ 読みやすい
~~"123"; // ❌ トリッキー3. 浮動小数点数への変換方法
3-1. parseFloat() 関数(推奨)
const str = "123.45";
const num = parseFloat(str);
console.log(num); // 123.45
console.log(typeof num); // "number"特徴:
- ✅ 小数点を保持
- ✅ 先頭の数値のみ抽出
- ❌ 基数指定不可(常に10進数)
実際の変換例
// 小数点文字列
parseFloat("123.45"); // 123.45
parseFloat("123.456789"); // 123.456789
// 整数文字列
parseFloat("123"); // 123
// 科学的記数法
parseFloat("1.23e2"); // 123
parseFloat("1.23E-2"); // 0.0123
// 先頭の数値を抽出
parseFloat("123.45abc"); // 123.45
parseFloat("123.45px"); // 123.45
// 空白を無視
parseFloat(" 456.78 "); // 456.78
// 先頭が数字でない場合
parseFloat("abc123.45"); // NaN
parseFloat(""); // NaN
// Infinity
parseFloat("Infinity"); // Infinity
parseFloat("-Infinity"); // -Infinity3-2. Number() コンストラクタ
const str = "123.45";
const num = Number(str);
console.log(num); // 123.45特徴:
- ✅ 文字列全体を厳密に変換
- ❌ 数値以外の文字があるとNaN
// 成功例
Number("123"); // 123
Number("123.45"); // 123.45
Number("1.23e2"); // 123
Number(" 456 "); // 456(前後の空白はOK)
// 失敗例(NaN)
Number("123abc"); // NaN(parseFloatなら123.45)
Number("123.45px"); // NaN
Number(""); // 0(注意!)
// 特殊な値
Number("Infinity"); // Infinity
Number(null); // 0
Number(undefined); // NaN3-3. 単項プラス演算子(+)
const str = "123.45";
const num = +str;
console.log(num); // 123.45特徴:
- ✅ 最も短い記法
- ✅ Number() と同じ動作
- ❌ 可読性が低い
// Number() と同じ
+"123"; // 123
+"123.45"; // 123.45
+"123abc"; // NaN
+""; // 0
// よく使われるパターン
const age = +document.getElementById('age').value;
const price = +data.price;4. Number() vs parseInt() vs parseFloat()
4-1. 機能比較表
| 項目 | Number() | parseInt() | parseFloat() |
|---|---|---|---|
| 整数変換 | ✅ | ✅ | △(小数点保持) |
| 小数点保持 | ✅ | ❌ | ✅ |
| 部分的な変換 | ❌ | ✅ | ✅ |
| 基数指定 | ❌ | ✅ | ❌ |
| 空文字列 | 0 | NaN | NaN |
| 厳密性 | 高い | 低い | 低い |
4-2. 実例比較
const input = "123.45abc";
Number(input); // NaN(文字が含まれるため失敗)
parseInt(input); // 123(整数部分のみ抽出)
parseFloat(input); // 123.45(数値部分を抽出)
+input; // NaN(Number()と同じ)4-3. 使い分けのフローチャート
文字列を数値に変換したい
↓
全体が数値か?
├─ YES → Number() または +演算子
│ 例: "123" → 123
│
└─ NO → 先頭に数値がある?
├─ YES → 整数が欲しい?
│ ├─ YES → parseInt(str, 10)
│ │ 例: "123px" → 123
│ │
│ └─ NO → parseFloat(str)
│ 例: "123.45px" → 123.45
│
└─ NO → デフォルト値を使う
例: Number(str) || 05. 型強制(Type Coercion)
5-1. 暗黙的な型変換
// 文字列 + 数値 → 文字列結合
"10" + 5; // "105"
5 + "10"; // "510"
// 文字列 - 数値 → 数値計算(引き算は数値のみ)
"10" - 5; // 5
"10" * "5"; // 50
"10" / "2"; // 5
// 比較演算子
"10" == 10; // true(型変換される)
"10" === 10; // false(厳密等価)5-2. 危険な自動変換
// ⚠️ 意図しない動作
const a = "10";
const b = "5";
const result = a + b;
console.log(result); // "105"(文字列結合!)
// ✅ 正しい方法
const result = Number(a) + Number(b); // 15
// または
const result = +a + +b; // 155-3. 実務での落とし穴
// フォーム入力の合計(よくあるバグ)
const price1 = document.getElementById('price1').value; // "100"
const price2 = document.getElementById('price2').value; // "200"
// ❌ 間違い
const total = price1 + price2; // "100200"
// ✅ 正しい
const total = Number(price1) + Number(price2); // 300
// ✅ または
const total = +price1 + +price2; // 3006. NaNの扱いと判定
6-1. NaN とは
// NaN = Not-a-Number(数値でない)
Number("abc"); // NaN
parseInt("xyz"); // NaN
parseFloat(""); // NaN
// NaN の特殊な性質
NaN === NaN; // false(!)
NaN == NaN; // false6-2. NaN の判定方法
// ❌ 間違った判定
const value = Number("abc");
if (value === NaN) { // 常にfalse
console.log("数値でない");
}
// ✅ 正しい判定方法1: isNaN()
if (isNaN(value)) {
console.log("数値でない");
}
// ✅ 正しい判定方法2: Number.isNaN()(推奨)
if (Number.isNaN(value)) {
console.log("数値でない");
}6-3. isNaN() vs Number.isNaN()
// isNaN() - 型変換してから判定
isNaN("abc"); // true
isNaN("123"); // false("123"は数値に変換できる)
isNaN(undefined); // true
isNaN({}); // true
// Number.isNaN() - 厳密な判定(推奨)
Number.isNaN("abc"); // false(文字列なのでNaNではない)
Number.isNaN(NaN); // true
Number.isNaN(Number("abc")); // true
Number.isNaN(123); // false推奨:
// 変換してから判定
const value = Number(input);
if (Number.isNaN(value)) {
console.log("数値に変換できません");
}6-4. 実務でのNaN対策
// デフォルト値を設定
const age = Number(input) || 0; // NaNなら0
// null合体演算子(ES2020)
const price = Number(input) ?? 0; // NaNは0に、nullも0に
// 関数化
function toNumber(value, defaultValue = 0) {
const num = Number(value);
return Number.isNaN(num) ? defaultValue : num;
}
const age = toNumber(input, 18); // 変換失敗なら187. よくあるエラーと対処法
エラー1: 文字列結合になってしまう
// ❌ 問題
const a = "10";
const b = "5";
const sum = a + b; // "105"
// ✅ 解決策1
const sum = Number(a) + Number(b); // 15
// ✅ 解決策2
const sum = +a + +b; // 15
// ✅ 解決策3
const sum = parseInt(a, 10) + parseInt(b, 10); // 15エラー2: カンマ区切りの数値
// ❌ 変換できない
Number("1,234.56"); // NaN
parseFloat("1,234.56"); // 1(カンマで停止)
// ✅ 解決策
const str = "1,234.56";
const num = Number(str.replace(/,/g, '')); // 1234.56エラー3: 全角数字
// ❌ 変換できない
Number("123"); // NaN
parseInt("123"); // NaN
// ✅ 解決策(半角に変換)
function toHalfWidth(str) {
return str.replace(/[0-9]/g, (s) => {
return String.fromCharCode(s.charCodeAt(0) - 0xFEE0);
});
}
const str = "123";
const num = Number(toHalfWidth(str)); // 123エラー4: 空文字列の扱い
// Number() の場合
Number(""); // 0(注意!)
// parseInt() の場合
parseInt(""); // NaN
// parseFloat() の場合
parseFloat(""); // NaN
// 推奨: 明示的なチェック
const input = "";
const num = input === "" ? null : Number(input);エラー5: null と undefined
// Number() の場合
Number(null); // 0
Number(undefined); // NaN
// parseInt() の場合
parseInt(null); // NaN
parseInt(undefined); // NaN
// 推奨: null チェック
const value = input ?? 0; // null/undefined なら 0
const num = Number(value);8. 実務での使い分け
8-1. フォーム入力の処理
// ✅ 基本パターン
const age = Number(document.getElementById('age').value) || 0;
const price = parseFloat(document.getElementById('price').value) || 0;
// ✅ バリデーション付き
function getNumberInput(id, defaultValue = 0) {
const value = document.getElementById(id).value;
const num = Number(value);
return Number.isNaN(num) ? defaultValue : num;
}
const age = getNumberInput('age', 18);8-2. API レスポンスの処理
// ✅ 型安全な変換
const response = await fetch('/api/product');
const data = await response.json();
const product = {
id: Number(data.id),
price: parseFloat(data.price) || 0,
quantity: parseInt(data.quantity, 10) || 0,
inStock: Boolean(data.inStock)
};8-3. URL パラメータの処理
// ✅ URLSearchParams
const params = new URLSearchParams(window.location.search);
const page = Math.max(1, parseInt(params.get('page'), 10) || 1);
const limit = Math.max(10, parseInt(params.get('limit'), 10) || 10);
const sort = params.get('sort') || 'id';8-4. ローカルストレージ
// ✅ 保存
localStorage.setItem('count', '5');
localStorage.setItem('price', '123.45');
// ✅ 取得
const count = parseInt(localStorage.getItem('count'), 10) || 0;
const price = parseFloat(localStorage.getItem('price')) || 0;9. TypeScriptでの型変換
9-1. 型アサーション
// 型アサーション(実行時には何もしない)
const input = "123" as string;
const num = Number(input); // number型として推論
// 明示的な型注釈
const age: number = Number(input);
const price: number = parseFloat(priceString);9-2. 型ガード関数
// 型ガード関数
function isNumber(value: unknown): value is number {
return typeof value === 'number' && !Number.isNaN(value);
}
// 使用例
function processValue(input: string | number) {
const num = typeof input === 'string' ? Number(input) : input;
if (isNumber(num)) {
// ここでnumはnumber型として扱われる
console.log(num.toFixed(2));
}
}9-3. Zod での検証(推奨)
import { z } from 'zod';
// スキーマ定義
const numberSchema = z.coerce.number(); // 文字列を自動変換
// 検証
const result = numberSchema.safeParse("123");
if (result.success) {
console.log(result.data); // 123 (number型)
}
// より詳細なスキーマ
const ageSchema = z.coerce.number()
.int("整数である必要があります")
.positive("正の数である必要があります")
.max(150, "年齢は150以下である必要があります");10. チートシート(コピペ用)
10-1. 整数変換
// 推奨: parseInt()
parseInt("123", 10); // 123
parseInt("123.45", 10); // 123(小数点切り捨て)
parseInt("123abc", 10); // 123
parseInt(" 456 ", 10); // 456
// 基数指定
parseInt("1010", 2); // 10(2進数)
parseInt("FF", 16); // 255(16進数)
// Math関数
Math.floor(123.9); // 123(切り捨て)
Math.ceil(123.1); // 124(切り上げ)
Math.round(123.5); // 124(四捨五入)10-2. 浮動小数点変換
// 推奨: parseFloat()
parseFloat("123.45"); // 123.45
parseFloat("123.45abc"); // 123.45
parseFloat("1.23e2"); // 123
// Number()
Number("123.45"); // 123.45
Number("123.45abc"); // NaN(厳密)
// 単項プラス
+"123.45"; // 123.45
+"123.45abc"; // NaN10-3. 実務テンプレート
// フォーム入力(デフォルト値あり)
const age = Number(document.getElementById('age').value) || 0;
const price = parseFloat(document.getElementById('price').value) || 0;
// null安全
const value = input ?? "";
const num = value === "" ? null : Number(value);
// カンマ区切り対応
const num = Number("1,234.56".replace(/,/g, '')); // 1234.56
// NaN チェック付き
function toNumber(value, defaultValue = 0) {
const num = Number(value);
return Number.isNaN(num) ? defaultValue : num;
}
// URLパラメータ
const page = parseInt(new URLSearchParams(location.search).get('page'), 10) || 1;
// ローカルストレージ
const count = parseInt(localStorage.getItem('count'), 10) || 0;10-4. 推奨する選択フローチャート
// 1. 文字列全体が数値かわからない → Number() または +
const num = Number(input);
if (!Number.isNaN(num)) {
// 変換成功
}
// 2. 先頭に数値がある文字列 → parseInt() / parseFloat()
const width = parseInt("100px", 10); // 100
const height = parseFloat("50.5em"); // 50.5
// 3. 確実に数値文字列 → どれでもOK(Number推奨)
const id = Number("123"); // 123まとめ
覚えておくべきポイント
✅ 基本の使い分け:
- 厳密な変換:
Number()または+演算子 - 整数抽出:
parseInt(str, 10)(基数指定必須) - 小数抽出:
parseFloat(str)
✅ 注意点:
Number("")は 0 になる(parseInt/parseFloat は NaN)NaN === NaNは falseparseInt()は必ず基数を指定(第2引数)
✅ 実務での推奨:
- NaN判定は
Number.isNaN()を使う - デフォルト値は
|| 0または?? 0 - カンマ区切りは
replace(/,/g, '')で除去
開発経験から
JavaScriptの型変換は、PHPよりもさらに複雑で罠が多いです。
実際にあったトラブル例:
- フォーム入力の合計が “100200” になった(文字列結合)
parseInt("08")が古いブラウザで 0 に(8進数と解釈)Number("")が 0 になり、入力チェックが機能しなかった
明示的な型変換と適切なバリデーションで、これらは100%防げます。
最終更新: 2026年2月 | ES2024 (ECMAScript 2024) 対応
あなたにおすすめの記事
PHP関連:
