閉じる

JavaScriptで文字列を数値に変換する方法:Number, parseInt, 単項プラスの挙動と使い分け

JavaScriptの開発において、文字列を数値に変換する操作は、実務で頻繁に遭遇する基本的なタスクの一つです。

フォームから入力された値やAPIから取得したデータは、多くの場合、文字列としてプログラムに渡されます。

これらのデータを計算や比較に使用するためには、適切な数値型へと変換するプロセスが欠かせません。

JavaScriptには数値を変換するための手法が複数用意されており、それぞれに独自の挙動や特性が存在します。

プロジェクトの要件に合わせて最適な手法を選択しなければ、予期せぬバグや計算ミスを引き起こす原因となり得ます。

本記事では、主要な変換方法であるNumber()関数、parseInt()parseFloat()、そして単項プラス演算子の違いを詳しく見ていきます。

Number()関数を使用した厳密な変換

Number()関数は、引数に渡された値を数値に変換するためのグローバル関数です。

この関数はオブジェクトのコンストラクタとしても利用できますが、型変換の用途では関数として呼び出すのが一般的です。

Number()の最大の特徴は、変換に対して非常に厳密な挙動を示す点にあります。

JavaScript
// Number()を使用した基本的な変換
const str1 = "123";
const num1 = Number(str1);

console.log(num1);
console.log(typeof num1);

const str2 = "123.45";
const num2 = Number(str2);

console.log(num2);
実行結果
123
number
123.45

特殊な値に対する挙動

Number()関数は、数値として解釈できない文字が含まれている場合、即座にNaN(Not a Number)を返します。

例えば、”100px”のような単位付きの文字列を変換しようとすると、結果は数値の100ではなくNaNとなります。

この性質により、入力値が純粋な数字のみで構成されているかを確認したい場合に非常に有効です。

また、nulltruefalseといったプリミティブ値に対しても特定の変換ルールが適用されます。

JavaScript
// 特殊な値の変換例
console.log(Number(""));          // 空文字
console.log(Number("  "));        // 空白のみ
console.log(Number(true));        // 真偽値(真)
console.log(Number(false));       // 真偽値(偽)
console.log(Number(null));        // null値
console.log(Number(undefined));   // undefined
console.log(Number("100px"));     // 単位付き文字列
実行結果
0
0
1
0
0
NaN
NaN

空文字や空白、null0に変換される点は、ロジックを組む上で注意が必要です。

特に、データが存在しないことを意味するnullが0として計算されてしまうと、統計処理などで誤った結果を招く恐れがあります。

一方で、undefinedを変換した場合はNaNとなるため、変数の初期化状態によって結果が異なることを覚えておきましょう。

parseInt()とparseFloat()によるパース処理

文字列から数値を「抽出」したい場合には、parseInt()parseFloat()が適しています。

これらはNumber()とは異なり、文字列の先頭から順に走査し、数値として解釈できる部分までを抽出する「パース(解析)」という仕組みを持っています。

このため、”100px”や”20rem”といった、数値で始まり後ろに単位が続くような文字列からも数値を取り出すことが可能です。

parseInt()で整数を取得する

parseInt()は、文字列を解析して整数を返します。

小数点が含まれる文字列を渡した場合、小数点以下は切り捨てられる点に注意してください。

JavaScript
// parseInt()による整数の抽出
const size = "42px";
const value = parseInt(size, 10);

console.log(value);

const price = "99.99";
console.log(parseInt(price, 10));
実行結果
42
99

基数(Radix)の指定について

parseInt()を使用する際には、第2引数に「基数」を指定することが強く推奨されます。 基数とは、その数値が何進法であるかを示す値であり、通常は10進法を意味する「10」を指定します。

過去のJavaScript仕様では、先頭が「0」で始まる文字列を8進法として誤認するケースがあり、予期せぬ動作を招くことがありました。

現在のモダンなブラウザでは改善されていますが、可読性と安全性を高めるために常にparseInt(string, 10)と記述する習慣をつけましょう。

parseFloat()で浮動小数点を取得する

小数点を含む数値を正確に取り出したい場合は、parseFloat()を使用します。

この関数は、最初の小数点までは数値の一部として認識し、それ以降の非数値が現れるまでを解析します。

JavaScript
// parseFloat()による浮動小数点の抽出
const weight = "65.5kg";
const result = parseFloat(weight);

console.log(result);

const version = "1.2.3";
console.log(parseFloat(version));
実行結果
65.5
1.2

上記の例のように、”1.2.3″のような文字列では、2つ目の小数点以降は無視されます。

また、parseFloat()にはparseInt()のような基数の引数は存在せず、常に10進数として解析が行われます。

単項プラス演算子(+)による簡潔な変換

JavaScriptには、最も短く記述できる数値変換の方法として、単項プラス演算子(+)が存在します。

変換したい文字列の直前にプラス記号を置くだけで、その値を数値型にキャストしようと試みます。

内部的な挙動はNumber()関数とほぼ同一であり、厳密な変換が行われます。

JavaScript
// 単項プラス演算子による変換
const str = "500";
const num = +str;

console.log(num);
console.log(typeof num);

console.log(+"10.5");
console.log(+"abc");
実行結果
500
number
10.5
NaN

この手法は、コードを非常に簡潔に書けるため、多くの開発者に好まれています。

しかし、一見すると「正の数であることを示している」だけに見えるため、初学者にとっては型変換が行われていることが分かりにくいというデメリットもあります。

チーム開発においては、可読性を優先してNumber()を明示的に使用するか、簡潔さを取ってプラス演算子を使うかのルールを決めておくことが望ましいです。

各手法の挙動比較と違い

これまでに紹介した3つの主な手法について、入力値による挙動の違いを整理しましょう。

適切なメソッドを選択するためには、特に「変換不能な文字が含まれる場合」と「空の値を扱う場合」の差異を理解することが重要です。

入力値Number() / +parseInt()parseFloat()
“123”123123123
“123.45”123.45123123.45
“100px”NaN100100
“” (空文字)0NaNNaN
null0NaNNaN

この表から分かる通り、Number()系は「文字列全体が正しい数値か」を厳密にチェックします。

対して、parseInt()系は「数値として読める部分があるか」を寛容にチェックします。

また、空の入力に対してNumber()0を返すのに対し、パース系メソッドがNaNを返すという違いは、フォームのバリデーション実装において極めて重要な分岐点となります。

「未入力(空文字)」を「0」として扱いたくない場合は、パース系を使用するか、事前に空文字のチェックを行う必要があるでしょう。

数値変換後のバリデーション(NaNチェック)

文字列を数値に変換した際、変換に失敗するとNaNという特別な値が返されます。

NaNは数値型(typeof NaN === "number")でありながら、計算ができない状態を指します。

厄介なことに、NaNは自分自身を含むあらゆる値と比較してもfalseを返すという性質を持っています。

JavaScript
// NaNの比較における注意点
const result = Number("invalid");

console.log(result === NaN);
実行結果
false

このように、=== NaNという条件式では変換の失敗を判定することができません。

変換が成功したかどうかを確実に判定するには、Number.isNaN()メソッドを使用します。

JavaScript
// 正しいNaNの判定方法
const input = "abc";
const converted = Number(input);

if (Number.isNaN(converted)) {
    console.log("数値への変換に失敗しました。");
} else {
    console.log("変換成功:", converted);
}
実行結果
数値への変換に失敗しました。

グローバル関数のisNaN()も存在しますが、こちらは引数を数値に変換してから判定を行うため、意図しない挙動を示すことがあります。

モダンな開発においては、より厳密な判定が可能なNumber.isNaN()を使用することが標準的なプラクティスです。

より安全な変換のためのベストプラクティス

実際のアプリケーション開発では、単に型を変換するだけでなく、その後のロジックを考慮した安全な変換が求められます。

BigIntへの対応

2026年現在のJavaScript開発において、非常に大きな整数を扱う場合はNumber型(64ビット浮動小数点数)の精度限界に注意が必要です。

Number型が安全に扱える最大の整数は 2^53 - 1Number.MAX_SAFE_INTEGER)までです。

これを超える巨大な数値を扱う可能性がある場合は、BigInt()関数を使用します。

JavaScript
// BigIntへの変換
const largeStr = "9007199254740992";
const bigIntNum = BigInt(largeStr);

console.log(bigIntNum);
実行結果
9007199254740992n

ただし、BigIntは通常のNumber型と混ぜて計算することができないため、型を統一するなどの配慮が必要です。

論理和演算子(||)によるデフォルト値の指定

数値変換に失敗した際、プログラムを停止させずにデフォルトの値を代入したいケースがあります。

その場合、論理和演算子を利用してフォールバック値を設定することが一般的です。

JavaScript
// デフォルト値の設定
const input = "invalid_input";
const score = Number(input) || 0;

console.log(score);
実行結果
0

ただし、この手法では変換後の値が0になった場合も偽値とみなされ、右辺のデフォルト値が採用されてしまいます。

0を有効な入力として扱いたい場合は、Null合体演算子(??)とNumber.isNaN()を組み合わせた、より詳細な条件分岐を検討しましょう。

実践的な使い分けガイド

最後に、どのようなシーンでどの変換メソッドを採用すべきかの指針をまとめます。

まず、「ユーザー入力を厳密に数値として受け取りたい」場合は、Number()または単項プラス演算子を選択してください。

特にAPIのパラメータや計算ロジックに渡す値であれば、不正な文字が含まれていた際にNaNとして検出できる厳密さがメリットになります。

次に、「CSSのプロパティ値や、単位を含む文字列から数字だけを取り出したい」場合は、parseInt()parseFloat()が最適です。

“150px”から”150″を取得するといった処理は、パース系メソッドにしかできない得意分野です。

そして、「パフォーマンスを極限まで追求し、かつ簡潔に記述したい」コードベースであれば、単項プラス演算子が選ばれることが多いでしょう。

どのような場合でも、変換後の値がNaNになっていないかを確認するステップを挟むことで、実行時エラーの少ない堅牢なコードを記述できます。

JavaScriptの柔軟な型システムを理解し、これらのツールを使い分けることで、データ処理の信頼性は大きく向上します。

まとめ

JavaScriptにおける文字列から数値への変換は、一見単純ですが、使用するメソッドによって挙動が大きく異なります。

Number()関数と単項プラス演算子は、文字列全体を数値として評価する厳密な変換に適しています。

一方、parseInt()parseFloat()は、文字列の先頭から数値を解析して抽出する柔軟な特性を持っています。

特に空文字やnullの扱い、基数の指定、そして変換失敗時のNaN判定など、細かい仕様の差異がプログラムの結果を左右します。

用途に応じて最適なメソッドを選択し、必要に応じてNumber.isNaN()によるチェックを行うことが、高品質なコードを書くための鍵となります。

それぞれの特徴を正しく把握し、意図した通りの数値変換を実現しましょう。

URLをコピーしました!