本文 AI 產出,尚未審核

JavaScript 數學與數字處理 – Number 物件方法(isNaN、isFinite、parseInt…)


簡介

在 JavaScript 中,數字是程式邏輯、使用者輸入驗證、資料庫查詢、圖形繪製等各種情境的基礎。雖然 Number 看似簡單,但它的行為卻常常讓新手感到困惑:NaNInfinity 的判斷、字串轉成數字的細節、以及不同環境下全域函式與 Number 靜態方法的差異,都可能成為 bug 的根源。

本篇文章聚焦在 Number 物件常用的幾個方法Number.isNaNNumber.isFiniteNumber.isIntegerparseIntparseFloat,以及與之相關的 toFixedtoPrecision。透過深入說明與實務範例,幫助你在日常開發中正確、有效率地處理數字與型別轉換。


核心概念

1. Number.isNaN vs 全域 isNaN

方法 目的 會自動型別轉換?
Number.isNaN(value) 僅在 value 本身是 NaN 時回傳 true
isNaN(value)(全域) 先把 value 轉成數字,若結果是 NaN,則回傳 true

為什麼要區分?
isNaN 的隱式型別轉換會把非數字字串、布林值等誤判為 NaN,在資料驗證時容易產生錯誤。

// 全域 isNaN 會先轉型
console.log(isNaN('123'));   // false  → 先變成 123,再判斷不是 NaN
console.log(isNaN('foo'));   // true   → 轉成 NaN
console.log(isNaN(true));    // false  → true → 1

// Number.isNaN 只檢查原始值是否為 NaN
console.log(Number.isNaN('123')); // false
console.log(Number.isNaN(NaN));   // true
console.log(Number.isNaN('foo')); // false,因為字串本身不是 NaN

最佳實踐:在需要嚴格判斷「是否真的為 NaN」時,使用 Number.isNaN;若你想判斷「是否能被轉成有效數字」則可使用 Number.isFinite(見下)。


2. Number.isFinite vs 全域 isFinite

方法 目的 會自動型別轉換?
Number.isFinite(value) 僅在 value 為有限數字(非 NaN、非 Infinity、非 -Infinity)時回傳 true
isFinite(value)(全域) 先把 value 轉成數字,若結果是有限數字,則回傳 true
// 全域 isFinite 會把字串轉成數字
console.log(isFinite('10'));   // true
console.log(isFinite('abc'));  // false → 轉成 NaN

// Number.isFinite 必須是已經是數字型別
console.log(Number.isFinite(10));      // true
console.log(Number.isFinite('10'));    // false
console.log(Number.isFinite(Infinity)); // false

使用情境

  • 表單驗證:確保使用者輸入的是「真實的有限數字」時,建議先 Number(value) 再使用 Number.isFinite
  • 計算安全性:在做除法或指數運算前,先檢查分母或底數是否為有限,避免 InfinityNaN 造成後續錯誤。

3. parseIntparseFloatNumber 建構子

方法 作用 會忽略什麼 進位基數
parseInt(string, radix) 從字串最左側開始解析,直到遇到非數字字符為止,回傳 整數 前導空白、非數字字元 可指定 2~36(預設 10,若字串以 0x 開頭則自動為 16)
parseFloat(string) 同上,但允許小數點與指數符號,回傳 浮點數 前導空白、非數字字元 只支援十進位
Number(string) 完全把字串轉成數字,若字串不是合法數字則回傳 NaN 前導/尾端空白會被忽略,整體必須是合法的數字表示 只支援十進位(含科學記號)
// parseInt 只會解析到第一個非數字字符
console.log(parseInt('42px'));          // 42
console.log(parseInt('0xFF'));          // 255 (十六進位)
console.log(parseInt('101', 2));        // 5  (二進位)

 // parseFloat 允許小數點與指數
console.log(parseFloat('3.14abc'));     // 3.14
console.log(parseFloat('2e3'));         // 2000

// Number 需要整體符合數字格式
console.log(Number('123'));             // 123
console.log(Number('123abc'));          // NaN
console.log(Number('   7   '));         // 7  (前後空白會被剔除)

小技巧

  • 若你只需要「把字串轉成完整的數字」且不想容忍後面的雜訊,使用 Number+(一元正號)是最安全的。
  • parseInt 常在 CSS 計算字串前綴(如 data-id="123-item")中使用,但要注意基數的正確設定,避免意外的十六進位解析。

4. Number.isInteger

判斷一個值是否為 整數(不含小數點、指數等),且必須是 Number 類型。

console.log(Number.isInteger(10));      // true
console.log(Number.isInteger(10.0));    // true  (10.0 仍被視為整數)
console.log(Number.isInteger(10.5));    // false
console.log(Number.isInteger('10'));    // false  (字串不算)

此方法在 分頁、陣列索引、頁碼驗證 等需要整數的情境特別有用。


5. Number.prototype.toFixedtoPrecision

方法 目的 回傳值型別
num.toFixed(digits) 四捨五入至指定的小數位數,回傳 字串 string
num.toPrecision(precision) 依總位數(包含整數部)四捨五入,回傳 字串 string
let price = 12.34567;

// 只保留兩位小數
console.log(price.toFixed(2));   // "12.35"

// 以 4 位有效數字呈現
console.log(price.toPrecision(4)); // "12.35"

注意toFixed 會自動補零(例如 1.5.toFixed(3) → "1.500"),適合顯示金額或統計數值。


常見陷阱與最佳實踐

陷阱 說明 解決方式
NaN === NaNfalse NaN 與任何值(包括自己)比較都不相等。 使用 Number.isNaN(value) 來檢測。
全域 isNaN 產生誤判 會把 ' 'truenull 轉成 0,導致 false 結果。 改用 Number.isNaNNumber.isFinite
parseInt('08') 在舊版瀏覽器被視為八進位 早期 ECMAScript 會把以 0 開頭的字串當作八進位。 明確指定基數:parseInt('08', 10)
浮點數精度問題 0.1 + 0.2 !== 0.3 因二進位表示誤差。 使用 toFixedMath.round 或第三方精確數學函式庫(如 Decimal.js)。
Number('') 會得到 0 空字串被視為 0,可能不是預期行為。 先檢查字串長度或使用 trim() 再轉型。
toFixed 產生字串 若直接用於算術運算會自動轉成數字,但可能產生隱式型別轉換。 需要時使用 Number(num.toFixed(2))

最佳實踐總結

  1. 驗證數值時:先使用 Number(value) 轉型,接著 Number.isFinite + Number.isNaN 進行嚴格檢查。
  2. 解析字串時:若只要前綴數字,用 parseInt/parseFloat,但一定要指定基數;若需要完整、嚴格的轉換,用 Number
  3. 顯示結果:使用 toFixedtoPrecision,記得結果是字串,必要時再轉回 Number
  4. 避免隱式型別轉換:盡量不依賴全域 isNaNisFinite,改用 Number 靜態方法。

實際應用場景

1. 表單金額驗證

function validateAmount(input) {
  const raw = input.trim();               // 去除前後空白
  const amount = Number(raw);             // 完全轉成數字

  if (!Number.isFinite(amount)) {
    return '金額必須是有效的數字';
  }
  if (amount < 0) {
    return '金額不可為負數';
  }
  // 四捨五入到小數點第二位,避免浮點誤差
  const fixed = Number(amount.toFixed(2));
  return fixed;
}

// 範例
console.log(validateAmount(' 123.456 ')); // 123.46
console.log(validateAmount('abc'));       // '金額必須是有效的數字'

2. 分頁索引檢查

function getPage(data, pageStr, pageSize = 10) {
  const page = Number(pageStr);
  if (!Number.isInteger(page) || page < 1) {
    throw new Error('頁碼必須為正整數');
  }
  const start = (page - 1) * pageSize;
  return data.slice(start, start + pageSize);
}

3. 解析 CSS 計算式

function extractPixelValue(cssValue) {
  // 只取前面的數字部分,忽略單位
  const num = parseInt(cssValue, 10);
  if (Number.isNaN(num)) {
    throw new Error('不是有效的 pixel 值');
  }
  return num; // 回傳純數字
}

console.log(extractPixelValue('250px')); // 250

4. 科學計算與指數顯示

function formatScientific(num, sig = 4) {
  if (!Number.isFinite(num)) return String(num);
  return Number(num.toPrecision(sig));
}

console.log(formatScientific(0.000123456)); // 0.0001235
console.log(formatScientific(123456789, 3)); // 1.23e+8

總結

  • Number.isNaNNumber.isFiniteNumber.isInteger嚴格檢查 方法,避免全域函式的隱式型別轉換。
  • parseIntparseFloat 適合 從字串前綴擷取數字,但必須留意基數與字串結構。
  • Number()(或 +value)是 完整且安全 的字串→數字轉換,配合 Number.isFinite 可實作堅固的驗證邏輯。
  • toFixedtoPrecision 用於 顯示,記得它們回傳字串,必要時再轉回 Number
  • 熟悉這些方法的差異與限制,能讓你在 表單驗證、資料處理、UI 顯示、科學計算 等各種場景中寫出更可靠、可維護的程式碼。

掌握好這些基礎工具,你就能在 JavaScript 的數字世界裡游刃有餘,避免常見的陷阱,寫出更健全的程式!祝開發順利 🚀