在处理数值的时候,获取浮点数的整数和小数部分,是一种常见的操作,在 JavaScript 中有许多方法可以达到目的,但也正因为方法众多,所以哪种方法更好,也值得我们仔细研究一番。
1. parseInt
let num = 3.75;
console.log(parseInt(num)); // 3
num = -3.75;
console.log(parseInt(num)); // -3
parseInt(3.75),会先将 3.75 转换成字符串 ”3.75″, 然后在转换成 3.
这个方法是一个将字符串转换为整数的方法,如果参数不是一个字符串,则将其转换成字符串 ,性能开销大。
关键还有一个致命的问题:
console.log(parseInt(0.00000001)); // 1
console.log(parseInt(1000000000000000000000)); // 1
分析:
这是因为toString(),0.00000001.toString()===1e- 8 而 1000000000000000000000..toString() === 1e+21。
2. Math.ceil + Math.floor
Math.ceil() 向上取整
Math.floor() 向上取整
function trunc (num) {if (num>=0) {return Math.floor(num)
} else {return Math.ceil(num)
}
}
console.log(trunc(3.75)); // 3
console.log(trunc(-3.75)); // -3
使用 Math.round 和 Math.ceil 实现 trunc 方法,要比使用 parseInt 的性能好,因为省去了转字符串。我们可以用 jsperf 测一下:
3. Math.trunc()
console.log(Math.trunc(3.75)); // 3
console.log(Math.trunc(-3.75)); // -3
4. |
具体实现原理,请参考 ECMA-262 文档
log(3.75 | 0); // 3
console.log(-3.75 | 0); // -3
注意:
因为 bitwise 操作将操作数转为 Int32,所以它不能处理超过 32 位的数值取整,而 JavaScript 有效整数的范围是 53 位。
const num = 17179869184.89;
console.log(num | 0); // 0
console.log(Math.trunc(num)); // 17179869184
综上:所以如果要考虑压缩代码的大小,且明确知道数值范围不会超过 32 位整数的时候,可以考虑使用 | 0 取整。否则,还是使用 Math 方法吧。
附:性能测试 https://jsperf.com