阅读 1457

parseInt 是用于字符串,而不是用于数字

如果有一个小数需要转换成整数,你可能会想到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


欢迎订阅掘金专栏知乎专栏

关注下面的标签,发现更多相似文章
评论