iT邦幫忙

2022 iThome 鐵人賽

0
Modern Web

就是要搞懂 JavaScript 啦!系列 第 66

Day66 Type:parse 字串解析為數字

  • 分享至 

  • xImage
  •  

將字串「解析(parsing)」為數字的型別轉換,與使用 Number() 的強制轉型行為有所不同,以下說明 parseIntparseFloat 兩種方法。


parseInt

這裡來比較看看 parseInt()Number() 的行為:

console.log(Number("42"));   // 42
console.log(parseInt("42")); // 42

console.log(Number(" 42  "));   // 42
console.log(parseInt(" 42  ")); // 42

console.log(Number("42px"));   // NaN
console.log(parseInt("42px")); // 42

console.log(Number(""));   // 0
console.log(parseInt("")); // NaN

console.log(Number("\n"));   // 0
console.log(parseInt("\n")); // NaN

console.log(Number("abc"));	  // NaN
console.log(parseInt("abc")); // NaN

從上面可以看到,Number 無法允許任何非數字的字串(但會忽略空白);而 parseInt 接受非數字字串,但在遇到非數字時就停止解析,並回傳當前結果。

另外,Number() 將空字串或空白字串視為 0 ,而 parseInt() 在第一個字符無法轉換為數字,或完全沒有字符能夠轉換時,會回傳 NaN

解析和強制轉型雖然有些相似,但目的完全不同。將一個 string 「解析」為 number,表示不知道或不關心傳入的字串是否擁有非數字內容;而將 string 「強制轉型」為 number,表示只接受純數字,不允許輸入其他內容。

字串化的過程

如果對 parseInt 傳入一個非字串,它首先會被強制轉型為 string,接著解析為數字:

console.log(Number(true));   // 1
console.log(parseInt(true)); // NaN

console.log(parseInt(function () { })); // NaN
console.log(parseInt([1, 2, 3]));       // 1,陣列被轉成了 "1,2,3" 進行解析
console.log(parseInt(["A", 2, 3])); // NaN
console.log(parseInt({}));          // NaN

理解 parseInt 的原理後,利用它 ToString 這部分強制轉型的過程,可以建構出自訂的 parseInt 方法:

var a = {
  num: 21,
  toString: function () {
    return String(this.num * 2);
  }
};

console.log(parseInt(a)); // 42

第二個參數

parseInt 也接受第二個參數,這個參數是一個基數(radix),也就是將收到的數字視為指定的進制來轉換。

parseInt 會根據收到的基數進行計算,將字串轉換為十進制的數字,如果沒有傳入第二個參數,parseInt 會根據慣例,猜測傳入的字串應該使用哪種進制看待。

比如十六進制的字串皆以 0x0X 開頭,遇到這樣的字串時,就會預設為十六進制轉十進制;但如八進制則是以 0 開頭,與常見的填充數彼此不易分辨,最後被視為普通的十進制來轉換。

console.log(parseInt("11111", 2));	// 31
console.log(parseInt("103", 2)); // 2
// 3 不是二進制合法的字符,實際解析的是 "10"

console.log(parseInt("070", 8));	  // 56
console.log(parseInt("0x36", 16));	// 54

// 失去第二個參數
console.log(parseInt("070"));	  // 70
console.log(parseInt("0x36"));	// 54

由於 parseInt 的預設值不總是為十進位,因此使用 parseInt 時建議總是傳入第二個參數以避免困惑,或發生非預期的結果。

除此之外,由於 parseInt 傳入非字串後會經過 ToString 強制轉型,一般情況下並不建議傳入字串以外的參數,以避免非預期的結果:

console.log(parseInt(0.000008)); // 0
// 得到的字串為 "0.000008"

console.log(parseInt(0.0000008)); // 8
// 得到的字串為 "8e-7"

console.log(parseInt(false, 16)); // 250
// 得到的字串為 "false",實際解析的是 "fa"

console.log(parseInt(parseInt, 16)); // 15
// 得到的字串為 "function parseInt(){...}",實際解析的是 "f"

console.log(parseInt(103, 2)); // 2
// 3 不是二進制合法的字符,實際解析的是 "10"

console.log(parseInt(1/0, 19)); // 18
// 得到的字串為 "Infinity",實際解析的是 "I"

parseFloat

parseFloatparseInt 十分相似,不同之處在於 parseFloat 只接受一個參數(也就是將收到的值一律視為十進位),並會將其解析為一個浮點數。

如果收到的參數並非字串,同樣會先進行 ToString 強制轉型再進行解析:

console.log(parseFloat(4.567)); // 4.567
console.log(parseFloat('4.567abcde356fgh42')); // 4.567
console.log(parseFloat('abcdefgh')); // NaN
console.log(parseFloat(true)); // NaN
console.log(parseFloat([0])); // 0

參考資料


上一篇
Day65 Type:JSON.stringify
下一篇
Day67 Async:事件循環
系列文
就是要搞懂 JavaScript 啦!73
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言