搞懂 parseInt() 的怪異行為

前端小智發表於2022-03-21
本文首發於微信公眾號:大遷世界, 我的微信:qq449245884,我會第一時間和你分享前端行業趨勢,學習途徑等等。
更多開源作品請看 GitHub https://github.com/qq449245884/xiaozhi ,包含一線大廠面試完整考點、資料以及我的系列文章。

快來免費體驗ChatGpt plus版本的,我們出的錢
體驗地址:https://chat.waixingyun.cn
可以加入網站底部技術群,一起找bug.

parseInt()是內建的 JS 函式,用於解析數字字串中的整數。 例如,解析數字字串'100'

const number = parseInt('100');
number; // 100

如預期的那樣,'100'被解析為整數 100

parseInt(numericalString, radix)還接受第二個引數:從 2 到 36,表示字串的基數。例如指定 16 表示被解析值是十六進位制數。請注意,10 不是預設值,最常見的是 2、8、10 和 16。

例如我們使用 parseInt 以二進位制方式解析數字字串:

const number = parseInt('100', 2);
number; // 4

100 對應的二進位制數是 4,所以返回 4。

1. parseInt() 的怪異行為

parseInt(numericalString)始終將其第一個引數轉換為字串(如果不是字串),然後將該數字字串解析為整數值。

這就是為什麼你可以(但不應該)使用parseInt()提取浮點數的整數部分的原因:

parseInt(0.5);      // => 0
parseInt(0.05);     // => 0
parseInt(0.005);    // => 0
parseInt(0.0005);   // => 0
parseInt(0.00005);  // => 0
parseInt(0.000005); // => 0

提取浮點數的整數部分,如0.50.05等,結果為0, 這和預期的一樣。

那提取0.0000005的整數部分怎麼樣?

parseInt(0.0000005); // => 5

parseInt() 將浮點數 0.0000005 解析為 5。為什麼 parseInt(0.0000005) 有這樣一個怪異的行為?

2.解決parseInt()怪異行為

我們再看一看 parseInt(numericalString) 的第一個引數:如果它不是字串,則將其轉換為字串,然後解析,並返回解析後的整數。

這可能是第一個線索。

然後,我們嘗試將浮點數手動轉換為字串表示形式:

String(0.5);      // => '0.5'
String(0.05);     // => '0.05'
String(0.005);    // => '0.005'
String(0.0005);   // => '0.0005' 
String(0.00005);  // => '0.00005'
String(0.000005); // => '0.000005'

String(0.0000005); // => '5e-7'

顯式轉換為string(0.0000005)字串的行為與其他浮點數不同:它的表示方式是用指數的形式。

這是第二個重要的線索!

當指數符號被解析為整數時,我們會得到數字5

parseInt(0.0000005); // => 5
// same as
parseInt(5e-7);      // => 5
// same as
parseInt('5e-7');    // => 5

parseInt('5e-7')考慮第一個數字'5',但跳過'e-7'

謎團已揭開! 因為 parseInt() 始終將其第一個引數轉換為字串,所以小於10負6次方的浮點數將以指數表示。 然後 parseInt() 從 float 的指數表示法中提取整數。

另外,為了安全地提取浮點數的整數部分,建議使用 Math.floor() 函式:

Math.floor(0.5);      // => 0
Math.floor(0.05);     // => 0
Math.floor(0.005);    // => 0
Math.floor(0.0005);   // => 0
Math.floor(0.00005);  // => 0
Math.floor(0.000005); // => 0

Math.floor(0.0000005); // => 0

3.總結

parseInt() 是將數字字串解析為整數的函式。

嘗試使用parseInt()提取浮點數的整數部分時必須小心。

小於10的-6次方 (例如0.0000005,也就是5*10-7)的浮點數轉換成字串時被寫成指數表示法(例如5e-7是0.0000005的指數表示法)。這就是為什麼在 parseInt() 中使用這麼小的浮點數會導致意想不到的結果:只有指數表記的重要部分(例如 5e-7 中的 5)會被解析。

那麼現在大家可以試著解釋為什麼 parseInt(999999999999999999999)等於1?

~完,我是刷碗智,去保健了,下期見~


程式碼部署後可能存在的BUG沒法實時知道,事後為了解決這些BUG,花了大量的時間進行log 除錯,這邊順便給大家推薦一個好用的BUG監控工具 Fundebug

交流

有夢想,有乾貨,微信搜尋 【大遷世界】 關注這個在凌晨還在刷碗的刷碗智。

本文 GitHub https://github.com/qq449245884/xiaozhi 已收錄,有一線大廠面試完整考點、資料以及我的系列文章。

相關文章