本文 AI 產出,尚未審核
JavaScript 數字(Number)
簡介
在 JavaScript 中,**數字(Number)**是最常使用的原始資料型別之一。幾乎所有的算術運算、索引、計時、統計分析,都離不開它。即使是看似簡單的「字串長度」或「陣列索引」,背後也會被自動轉型成數字來處理。
因此,對 Number 的特性與限制有清晰的認識,不只能寫出正確的程式碼,更能避免常見的 精度誤差、隱式型別轉換 等陷阱,提升程式的可讀性與可維護性。本文針對初學者到中級開發者,系統說明 JavaScript 中的數字型別、常用方法與實務應用,並提供實作範例與最佳實踐建議。
核心概念
1. Number 的基本特性
- JavaScript 只有一種數值型別 Number(除了 ES2020 之後的
BigInt),它採用 IEEE‑754 雙精度浮點數(64 位元)表示。 - 整數與小數在語法上沒有差別,皆屬於同一個型別。
let a = 42; // 整數
let b = 3.14; // 浮點數
console.log(typeof a, typeof b); // "number" "number"
2. 特殊值:NaN、Infinity、-Infinity
| 值 | 說明 |
|---|---|
NaN |
Not a Number,表示「不是一個有效的數字」;任何與 NaN 的算術運算結果仍為 NaN。 |
Infinity |
正無限大,通常出現在除以 0 或超出可表示範圍的結果。 |
-Infinity |
負無限大。 |
console.log(0 / 0); // NaN
console.log(1 / 0); // Infinity
console.log(-1 / 0); // -Infinity
⚠️ 注意:
NaN === NaN為false,必須使用Number.isNaN()判斷。
3. 數值常用屬性與方法
| 屬性 / 方法 | 說明 |
|---|---|
Number.MAX_VALUE |
可表示的最大正數(約 1.79e+308)。 |
Number.MIN_VALUE |
可表示的最小正數(約 5e-324),非負零。 |
Number.isNaN(value) |
嚴格判斷是否為 NaN。 |
Number.isFinite(value) |
判斷是否為有限數(非 NaN、非 Infinity)。 |
Number.parseInt(str, radix) |
轉換字串為整數,第二參數 radix 為進位基數。 |
Number.parseFloat(str) |
轉換字串為浮點數。 |
num.toString(radix) |
以指定進位制(2~36)輸出字串。 |
num.toFixed(digits) |
四捨五入保留小數位,回傳字串。 |
num.toPrecision(precision) |
依有效位數返回字串。 |
程式碼範例
範例 1:使用 Number.isNaN 正確檢測 NaN
function safeDivide(a, b) {
const result = a / b; // 可能產生 NaN 或 Infinity
if (Number.isNaN(result)) {
return '除法結果不是有效數字';
}
if (!Number.isFinite(result)) {
return '除法結果為無限大';
}
return result;
}
console.log(safeDivide(10, 0)); // "除法結果為無限大"
console.log(safeDivide(0, 0)); // "除法結果不是有效數字"
console.log(safeDivide(5, 2)); // 2.5
範例 2:避免字串轉數字時的隱式進位錯誤
// 錯誤寫法:直接使用 Number() 轉型,若字串開頭為 "0x" 會被當成十六進位
let hex = "0xFF";
console.log(Number(hex)); // 255 (意外的十六進位解讀)
// 正確寫法:明確指定十進位基數
let decimal = Number.parseInt(hex, 10);
console.log(decimal); // NaN,因為 "0xFF" 不是十進位數字
範例 3:浮點數精度問題與 toFixed 的使用
let sum = 0.1 + 0.2; // 0.30000000000000004
console.log(sum); // 0.30000000000000004
// 使用 toFixed 取兩位小數,結果為字串
let rounded = sum.toFixed(2);
console.log(rounded); // "0.30"
console.log(Number(rounded) + 0.1); // 0.4,避免累積誤差
範例 4:parseInt 與基數的正確運用(常見陷阱)
let str1 = "08"; // 以 0 開頭的字串
console.log(Number.parseInt(str1)); // 8 (ES5 之後預設十進位)
let str2 = "1010";
console.log(Number.parseInt(str2, 2)); // 10,將二進位字串轉為十進位
範例 5:使用 BigInt 處理超大整數(ES2020)
// Number 無法正確表示超過 2^53-1 的整數
let large = 9007199254740993; // 超過安全範圍
console.log(large === large + 1); // true,失真
// 改用 BigInt
let big = 9007199254740993n; // 後綴 n 表示 BigInt
console.log(big === big + 1n); // false,正確比較
常見陷阱與最佳實踐
| 陷阱 | 說明 | 最佳實踐 |
|---|---|---|
| 浮點精度誤差 | 0.1 + 0.2 ≠ 0.3 | 使用 toFixed/toPrecision、或改用整數(如以「分」計算金額) |
| 隱式型別轉換 | == 會自動轉型,導致意外結果 |
永遠使用 ===,必要時手動 Number() 轉型 |
| NaN 比較 | NaN === NaN 為 false |
使用 Number.isNaN() 檢測 |
parseInt 省略基數 |
早期瀏覽器會把前導 0 當作八進位 |
永遠提供第二參數 radix |
| 大數超出安全範圍 | 超過 Number.MAX_SAFE_INTEGER 會失真 |
使用 BigInt 或第三方大數庫 |
Infinity 與除以 0 |
1 / 0 產生 Infinity,可能導致邏輯錯誤 |
在計算前檢查除數是否為 0,或使用 Number.isFinite 之後再使用結果 |
實際應用場景
金額計算
- 使用 整數(以「分」為單位)避免浮點誤差;最後顯示時再除以 100 並使用
toLocaleString格式化。
- 使用 整數(以「分」為單位)避免浮點誤差;最後顯示時再除以 100 並使用
分頁與索引
- 透過
Number.isInteger(page)確保使用者輸入的頁碼為正整數,防止非法索引。
- 透過
隨機數產生
Math.random()產生[0,1)的浮點數,配合Math.floor轉為整數區間。
function randomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }計時器與動畫
performance.now()回傳毫秒的浮點數,可用於高精度時間測量;使用requestAnimationFrame時,時間參數自帶高精度。
科學計算
- 需要控制有效位數時,使用
Number.toPrecision,例如顯示 3 個有效位數的結果。
- 需要控制有效位數時,使用
總結
- JavaScript 的 Number 只有一種,但涵蓋了整數、浮點數以及特殊值(NaN、Infinity)。
- 了解 IEEE‑754 的限制,才能在實務開發中避免精度錯誤與隱式型別轉換帶來的 bug。
- 使用
Number.isNaN、Number.isFinite、Number.parseInt(帶基數) 等嚴格檢測與轉換方法,是寫出健全程式碼的關鍵。 - 當需求超出安全整數範圍或需要極大數值時,
BigInt提供了可靠的解決方案。 - 在日常開發(金額、分頁、隨機、計時、科學計算)中,依照最佳實踐處理數字,可提升程式的正確性與可維護性。
掌握了上述概念與技巧後,你就能在 JavaScript 中自信地使用數字,無論是簡單的加減或是複雜的金融計算,都能寫出正確、可靠且易於維護的程式碼。祝你在程式之路上,數字永遠為你服務,而不是成為阻礙!