Javascript 中的数字截断(Number Truncation)
使用 Math.trunc()
来截断一个浮点数并返回它的整数部分。该函数不会做任何的舍入,它简单地删除小数部分。现在你得到了整数部分,yay 🎊
const number = 80.6
// Old Way
function truncNumber() {
number < 0 ? Math.ceil(number) : Math.floor(number)
}
truncNumber(number) // 80
// ✅ES6 Way
const es6 = Math.trunc(number) // 80
例子
Math.trunc()
简单地截断(剪除)数字小数点和小数点后面的部分。无论参数是正数还是负数。
Math.trunc(80.9) // 80
Math.trunc(80.8) // 80
Math.trunc(80.8) // 80
Math.trunc(80.6) // 80
Math.trunc(80.5) // 80
Math.trunc(80.4) // 80
Math.trunc(80.3) // 80
Math.trunc(80.2) // 80
Math.trunc(80.1) // 80
Math.trunc(-80.1) // -80
现在让我们看看转化非数字参数的例子:
Math.trunc('80.1') // 80
Math.trunc('hello') // NaN
Math.trunc(Number.NaN) // NaN
Math.trunc(undefined) // NaN
Math.trunc() // NaN
使用 parseInt 进行数字截断
使用 parseInt
你会获得相似的结果:
Number.parseInt(80.1) // 80
Number.parseInt(-80.1) // -80
Number.parseInt('80.1') // 80
Number.parseInt('hello') // NaN
Number.parseInt(undefined) // NaN
Number.parseInt() // NaN
Math.trunc() 与 parseInt() 相比
parseInt
主要用于数字参数。所以如果你正在处理数字,Math.trunc()
是更好的方法。
如果你对此好奇,我写过一个针对这两个函数的性能测试。
jsPerf(英文): Math.trunc() 与 parseInt() 相比
使用 parseInt 的缺陷
使用 parseInt
的潜在问题是,当你处理那些非字符串参数的时候,例如一个数字,它将首先使用 toString()
抽象操作将值转化为一个字符串。大多数情况下使用 parseInt
是运行良好的,但是让我看一个不好的例子:
const number = 1000000000000000000000.5
const result = Number.parseInt(number)
console.log(result) // 1 <-- 😱
☝️ 为什么会这样呢?因为我们的参数不是一个 string
,于是 parseInt
首先将这个参数转化为一个 string
。
const number = 1000000000000000000000.5
const result = number.toString()
console.log(result) // "1e+21"
所以当我们尝试从 1e+21
抓取整数部分,parseInt
只知道抓取值 1
。如此,使用 parseInt
确实有缺陷。因为这一边缘情况,你可能考虑使用 Math
的函数 👍
浏览器兼容性
大部分现代浏览器支持 Math.trunc()
,Internet Explorer 除外。我知道如果需要支持旧的浏览器是沮丧的(😞),请使用旧的方法 😕
Math.trunc
浏览器填充(Polyfill),在不支持的浏览器中提供服务:
if (!Math.trunc) {
Math.trunc = function (v) {
v = +v
if (!isFinite(v))
return v
return v - (v % 1) || (v < 0 ? -0 : v === 0 ? v : 0)
}
}
或:
if (!Math.trunc) {
Math.trunc = function (v) {
v = +v
return v - (v % 1) || (!isFinite(v) || v === 0 ? v : v < 0 ? -0 : 0)
}
}
社区支持
位操作符解决方法
双位操作符 ~~
console.log(~~80.6) // 80
感谢:twitter.com@Jorgert120
按位或(OR) |
console.log(80.6 | 0) // 80
感谢:twitter.com@mac_experts
toFixed 解决方法
你可以使用 .toFixed()
方法
;(80.645).toFixed() // “80”
虽然这个方法返回一个字符串,但是我们可以再次将它转化为数字:
Number((80.645).toFixed()) // 80
有一点凌乱,但是通过设置参数,你可以选择你想要位数的结果。
Number((80.645).toFixed(1)) // 80.6
感谢:medium.com@Frani 🍍
资源
- MDN Web Docs: Math.trunc
- MDN Web Docs: parseInt
- MDN Web Docs: Bitwise operators
- JS Tip: Use parseInt for strings, NOT for numbers
- parseInt() 不总是正确地转换为整数
文章由 吳文俊 翻译,原文地址 Number Truncation in JavaScript,转载请注明来源。