JavaScript における `Number` クラス

JavaScript における `Number` クラス

この記事ではJavaScript における Number クラスについて説明します。

Number の性質、よくある落とし穴、便利な API、実践的なサンプルを段階を踏んで丁寧に説明します。

YouTube Video

JavaScript における Number クラス

Number は JavaScript における基礎的な数値型であり、IEEE-754 倍精度浮動小数点(64-bit)で表現されます。

基本:数値の表現と型判定

JavaScript の数値はすべてプリミティブのnumber型で表されます。

 1// Primitive numbers and Number object
 2const a = 42;                 // primitive number
 3const b = 3.14;               // primitive float
 4const c = Number(10);         // primitive via constructor call (function form)
 5const d = new Number(10);     // Number object (wrapper)
 6
 7console.log(typeof a);        // "number"
 8console.log(typeof d);        // "object"
 9console.log(c == d);          // true  (value coerces)
10console.log(c === d);         // false (different types)
  • このコードは、プリミティブな numberNumber ラッパーオブジェクトの差を示します。通常はラッパーを使わずプリミティブを用います。

特殊値:NaNInfinity、定数

Number には特別な数値(NaNInfinity)や定数が用意されています。

 1// Special numeric values and constants
 2console.log(Number.NaN);                 // NaN
 3console.log(Number.POSITIVE_INFINITY);   // Infinity
 4console.log(Number.NEGATIVE_INFINITY);   // -Infinity
 5
 6console.log(Number.MAX_VALUE);           // largest positive representable
 7console.log(Number.MIN_VALUE);           // smallest positive representable (closest to 0)
 8console.log(Number.MAX_SAFE_INTEGER);    // 9007199254740991
 9console.log(Number.MIN_SAFE_INTEGER);    // -9007199254740991
10console.log(Number.EPSILON);             // smallest difference ~2.220446049250313e-16
  • MAX_SAFE_INTEGER 以上の整数は正確に表現できない場合があり、その必要がある場合は BigInt を検討します。EPSILON は浮動小数点比較で使います。

数値変換:Number()parseIntparseFloat+ 演算子

文字列から数値への変換には複数の方法があり、それぞれ挙動が違います。

 1// Converting strings to numbers
 2console.log(Number("42"));        // 42
 3console.log(Number("  3.14 "));   // 3.14
 4console.log(+ "7");               // 7 (unary +)
 5
 6console.log(parseInt("42px"));    // 42
 7console.log(parseFloat("3.14abc"));// 3.14
 8
 9// Careful with parseInt and radix
10console.log(parseInt("08"));      // 8
11console.log(parseInt("08", 10));  // 8 (explicit radix is safer)
  • Number() は文字列全体が厳密に数値形式でないと NaN を返しますが、parseIntparseFloatは先頭から数値として読める部分を解析します。parseInt には必ず基数を与える習慣を付けると安全です。

NaN の扱いと判定:isNaNNumber.isNaN

NaN(Not-A-Number)は特殊で、NaN !== NaN になります。判定方法に差があり、グローバル isNaN は型変換を行うため誤検出があり、Number.isNaN を推奨します。

1// NaN detection differences
2console.log(NaN === NaN);             // false
3
4console.log(isNaN("foo"));            // true  -> because "foo" coerces to NaN
5console.log(Number.isNaN("foo"));     // false -> "foo" is not the numeric NaN
6
7console.log(Number.isNaN(NaN));       // true
  • 数値チェックや演算結果の検証には Number.isNaN を使い、不要な型変換を避けます。

浮動小数点の誤差と Number.EPSILON を使った比較

IEEE-754 のために 0.1 + 0.2 !== 0.3 のような誤差が発生します。厳密比較では差分と Number.EPSILON を使う方法が一般的です。

1// Floating point precision example and EPSILON comparison
2const sum = 0.1 + 0.2;
3console.log(sum === 0.3);             // false
4
5function nearlyEqual(a, b, epsilon = Number.EPSILON) {
6  return Math.abs(a - b) <= epsilon * Math.max(1, Math.abs(a), Math.abs(b));
7}
8
9console.log(nearlyEqual(sum, 0.3));   // true
  • 誤差を許容する比較を行う場合、絶対差だけでなくスケーリングを行う nearlyEqual のような実装が堅牢です。

整数判定と安全な整数 (isIntegerisSafeInteger)

整数であるかどうかや、精度が保証される範囲かを確認する API があります。

1// Integer and safe integer checks
2console.log(Number.isInteger(3));                 // true
3console.log(Number.isInteger(3.0));               // true
4console.log(Number.isInteger(3.1));               // false
5
6console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER)); // true
7console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1)); // false
  • 大きな整数の正確性が必要なときは Number.isSafeInteger で検査し、超える場合は BigInt の利用を検討します。

表示とフォーマット:toFixedtoPrecisiontoString

数値の表示を制御するメソッドが用意されています。toFixed は小数点以下桁数を指定して文字列を返しますが、丸めに注意が必要です。

1// Formatting numbers for display
2const x = 1.23456;
3console.log(x.toFixed(2));         // "1.23"   (string)
4console.log(x.toPrecision(3));     // "1.23"   (string with total significant digits)
5console.log((255).toString(16));   // "ff"     (hexadecimal string)
  • toFixed は文字列を返すので、計算に利用する場合は変換した後の数値に注意してください。

文字列結合と + の注意点

+ 演算子は数値加算にも文字列連結にも使われるため、型に応じて意図しない結果が出ることがあります。

1// Pitfall with + operator and type coercion
2console.log(1 + 2 + "px");    // "3px"
3console.log("px" + 1 + 2);    // "px12"
4console.log(1 + "2" - 0);     // 3  (string coerced to number for subtraction)
  • 文字列と数値が混在する場合は暗黙変換を避けるため String()Number()、テンプレート文字列を明示的に使うと安全です。

高度なユースケース:Number.parseInt / Number.parseFloatvalueOf

Number.parseIntNumber.parseFloat はグローバル関数のエイリアスです。valueOfNumber オブジェクトからプリミティブ値を取り出すために使われますが、通常は必要ありません。

1// Number.parseInt/parseFloat aliases and valueOf example
2console.log(Number.parseInt("100", 10));   // 100
3console.log(Number.parseFloat("3.14"));    // 3.14
4
5const nObj = new Number(5);
6console.log(nObj.valueOf());               // 5
7console.log(nObj + 1);                     // 6  (object coerced to primitive)
  • Number.parseIntNumber.parseFloat を使うときも基数や入力のトリミングなどに気を付ける必要があります。ラッパーオブジェクトは通常避けます。

参考となる小さめのユーティリティ例:数値検証関数

よく使う判定をまとめた小さなユーティリティ関数を示します。これで入力検証などが楽になります。

 1// Small number utility functions
 2function toNumberStrict(value) {
 3  // Return a Number or throw for invalid numeric strings
 4  const n = Number(value);
 5  if (typeof value === "string" && value.trim() === "") {
 6    throw new Error("Empty string is not a valid number");
 7  }
 8  if (Number.isNaN(n)) {
 9    throw new Error(`Invalid number: ${value}`);
10  }
11  return n;
12}
13
14function almostEqual(a, b, eps = Number.EPSILON) {
15  // Robust relative comparison
16  return Math.abs(a - b) <= eps * Math.max(1, Math.abs(a), Math.abs(b));
17}
  • これらは入力処理や比較で繰り返し使える汎用性の高い関数です。エラーを投げる実装はバリデーション用途で便利です。

パフォーマンスとベストプラクティスのまとめ

以下は、Numberを利用する際の実用的な点です。

  • 基本はプリミティブ number を使い、new Number() は避けます。
  • 文字列→数値変換は用途により Number()(厳密)か parseInt/parseFloat(部分抽出)を使い分けます。
  • Number.isNaNNumber.isFinite を利用して安全にチェックします。
  • 浮動小数点比較は Number.EPSILON を使うか専用の比較関数を作ります。
  • 整数の正確さが必要な場合は Number.isSafeInteger を確認し、越えるなら BigInt を使います。
  • 表示用の丸めにはtoFixedtoPrecisionを使えますが、返り値が文字列であることに注意します。

まとめ

Number は JavaScript のすべての数値を扱う基本型であり、整数・小数・特殊値(NaNInfinity)を含みます。型変換や浮動小数点の誤差に注意しつつ、Number.isNaNNumber.EPSILON などのメソッドを正しく使うことが重要です。安全な整数範囲を超える場合は BigInt を利用し、丸めや表示には toFixedtoPrecision を活用しましょう。

YouTubeチャンネルでは、Visual Studio Codeを用いて上記の記事を見ながら確認できます。 ぜひYouTubeチャンネルもご覧ください。

YouTube Video