1. 程式人生 > 實用技巧 >【JavaScript】標準內建函式 parseInt

【JavaScript】標準內建函式 parseInt

以下內容為學習記錄,可以參考 MDN 原文。

環境

  • node v12.18.1
  • npm 6.14.5
  • vscode 1.46
  • Microsoft Edge 83

概念

parseInt(string, radix) 將一個字串 string 轉換為 radix 進位制的整數, radix 為介於 2-36 之間的數。
parseInt 函式將其第一個引數轉換為一個字串,對該字串進行解析,然後返回一個整數或 NaN。

如果不是 NaN,返回值將是第一個引數的整數,即第一個引數作為指定的 radix 的數字。(例如,radix 為 10,就是可以轉換為十進位制數,為 8 可以轉換為八進位制數,16 可以轉換為十六進位制數,以此類推)。

對於 radix 為 10 以上的,英文字母表示大於 9 的數字。例如,對於十六進位制數(基數16),則使用 A 到 F 。

如果 parseInt 遇到的字元不是指定 radix 引數中的數字,它將忽略該字元以及所有後續字元,並返回到該點為止已解析的整數值。 parseInt 將數字截斷為整數值。允許前導和尾隨空格。

由於某些數字在其字串表示形式中使用 e 字元(例如 6.022×23 表示 6.022e23 ),因此當對非常大或非常小的數字使用數字時,使用 parseInt 截斷數字將產生意外結果。 parseInt 不應替代 Math.floor()。

parseInt 可以理解兩個符號。+ 表示正數,- 表示負數(從ECMAScript 1開始)。它是在去掉空格後作為解析的初始步驟進行的。如果沒有找到符號,演算法將進入下一步;否則,它將刪除符號,並對字串的其餘部分進行數字解析。

如果 radix 是 undefined、0 或未指定的,JavaScript 會假定以下情況:

  1. 如果輸入的 string 以 "0x" 或 "0x"(一個0,後面是小寫或大寫的X)開頭,那麼 radix 被假定為 16,字串的其餘部分被解析為十六進位制數。
  2. 如果輸入的 string 以 "0"(0)開頭, radix 被假定為 8(八進位制)或 10(十進位制)。具體選擇哪一個 radix 取決於實現。ECMAScript 5 澄清了應該使用 10 (十進位制),但不是所有的瀏覽器都支援。因此,在使用 parseInt 時,一定要指定一個 radix。
  3. 如果輸入的 string 以任何其他值開頭, radix 是 10 (十進位制)。
  4. 如果第一個字元不能轉換為數字,parseInt會返回 NaN。

為了算術的目的,NaN 值不能作為任何 radix 的數字。你可以呼叫 isNaN 函式來確定 parseInt 的結果是否為 NaN。如果將 NaN 傳遞給算術運算,則運算結果也將是 NaN。

要將一個數字轉換為特定的 radix 中的字串欄位,請使用 thatNumber.toString(radix) 函式。

使用 parseInt

parseInt("0xF", 16);
parseInt("F", 16);
parseInt("17", 8);
parseInt(021, 8);
parseInt("015", 10);   // parseInt(015, 10); 返回 13
parseInt(15.99, 10);
parseInt("15,123", 10);
parseInt("FXX123", 16);
parseInt("1111", 2);
parseInt("15 * 3", 10);
parseInt("15e2", 10);
parseInt("15px", 10);
parseInt("12", 13);

parseInt 返回 NaN

parseInt("Hello", 8); // 根本就不是數值
parseInt("546", 2);   // 除了“0、1”外,其它數字都不是有效二進位制數字

沒有指定 radix 引數時的八進位制解析

儘管 ECMAScript 3 已經不贊成這種做法,且 ECMAScript 5 已經禁止了這種做法,但是仍然有很多實現環境仍然把以 0 開頭的數值字串(numeric string)解釋為一個八進位制數。下面的例子可能返回八進位制的結果,也可能返回十進位制的結果。總是指定一個基數(radix)可以避免這種不可靠的行為。

parseInt("0e0"); 
// 0

parseInt("08"); 
// 0, '8' 不是八進位制數字.

ECMAScript 5 移除了八進位制解析

ECMAScript 5 規範不再允許 parseInt 函式的實現環境把以 0 字元開始的字串作為八進位制數值。ECMAScript 5 陳述如下:

根據給定 radix,parseInt 函式產生一個由字串引數內容解析過來的整數值。字串中開頭的空白會被忽略。如果 radix 沒有指定或者為 0,引數會被假定以 10 為基數來解析,如果數值以字元對 0x 或 0X 開頭,會假定以 16 為基數來解析。

這與 ECMAScript 3 有所不同,ECMAScript 3 僅僅是不提倡這種做法但並沒有禁止這種做法。

直至 2013 年,很多實現環境並沒有採取新的規範所規定的做法, 而且由於必須相容舊版的瀏覽器,所以永遠都要明確給出 radix 引數的值.

一個更嚴格的解析函式

filterInt = function (value) {
  if(/^(\-|\+)?([0-9]+|Infinity)$/.test(value))
    return Number(value);
  return NaN;
}

console.log(filterInt('421'));               // 421
console.log(filterInt('-421'));              // -421
console.log(filterInt('+421'));              // 421
console.log(filterInt('Infinity'));          // Infinity
console.log(filterInt('421e+0'));            // NaN
console.log(filterInt('421hop'));            // NaN
console.log(filterInt('hop1.61803398875'));  // NaN
console.log(filterInt('1.61803398875'));     // NaN