parseInt 是用於字串,而不是用於數字

yuyurenjie發表於2019-03-01

如果有一個小數需要轉換成整數,你可能會想到parseInt():

parseInt(1.655)
//1複製程式碼

但是,如果這樣:

parseInt(0.00000060)
//6複製程式碼

跟我們設想的結果不一樣。。。

如果在DevTools中輸入0.000000006,會返回結果6e-9。當有連續的0,會輸出這樣科學計數法的形式。

這樣我們就只能趕緊去MDN看看對於parseInt的解釋

parseInt() 函式解析一個字串引數,並返回一個指定基數的整數 (數學系統的基礎)。
parseInt 函式將其第一個引數轉換為字串,解析它,並返回一個整數或NaN。如果不是NaN,返回的值將是作為指定基數(基數)中的數字的第一個引數的整數。

回到上面例子中,我們輸入0.000000006,會首先將其變成6e-9,然後將其轉換為字串,但是遇到了不是數字的e,雖然e的值為2.718,但是仍是在此停止轉換,然後返回值為6

現在讓我們輸入字串0.000000006,就會返回正確的結果:

parseInt(`0.000000006`)
//0複製程式碼

到這裡可以看出,parseInt方法不是特別安全,它在某些方面無法做到返回正確結果,一種的解決方法是將要轉換的數字放入雙引號之間"".

然而這個方法不是太好,如果當我們遇到這樣問題,可以嘗試下面的方法

方法1

可以使用Math方法對數字進行四捨五入或截斷,例如:Math.roundMath.ceilMath.floorMath.trunc

Math.trunc會從小數點開始擷取,而且不採用任何四捨五入方法。

Math.trunc(1.655)  
// 1複製程式碼
Math.trunc(0.000000006)  
// 0複製程式碼

對於不能使用ES6的瀏覽器,也可以採用下面的polyfill:

function ToInteger(v) {  
    if (v > 0) {
        return Math.floor(v);
    }
    return Math.ceil(v);
}

ToInteger(0.000000006) 
//0複製程式碼

方法2

較為快速的方法轉換為整數方法是採用位運算。在JavaScript中位運算是將運算元轉換為32位有符號的數,然後對其進行位運算。

可以使用或運算:

1.655 | 0
//1複製程式碼

1.655轉換為0b00000001,然後與0進行或運算,有一個1,則運算後結果為1,如果都為0,則結果為0

00000001  
   |
00000000  
-> 00000001複製程式碼

最後得到`1“,這樣就能得到我們想要的結果。

此方法缺點在於對於輸入的數字有要求,只能用於32位二進位制能代表的,超過32位則會出錯。

如果我們嘗試轉換4000000000000000000000.1

4000000000000000000000.1 | 0  
// 2055208960複製程式碼

但是方法1沒有此問題,所以如果沒有大數(超過+/-2^32),則建議使用位運算,否則則使用Math.trunc

參考資料

MDN parseInt
use-parseint-for-strings-not-for-numbers


歡迎訂閱掘金專欄知乎專欄

相關文章