在前端开发中,处理数字是非常常见的操作之一。而遇到一些输入不可靠的情况时,比如来自用户输入或者第三方数据源的字符串,如何准确地将其转换为数字就成为了一个难题。ES12 中引入了一个新的特性:更可靠的 Number Parsing,可以帮我们更方便地解决这个问题。
Number Parsing 的问题
在传统的 JavaScript 中,将字符串转换为数字一般是通过 parseInt
或 parseFloat
来实现的。不过这些方法存在许多问题,比如:
输入不可靠:
parseInt
和parseFloat
都只会解析输入字符串的开始部分,并忽略掉结尾的非数字字符,这可能导致一些数字被误解析。parseInt("2.7 apples"); // 2 parseFloat("$2.99"); // 2.99
无法检测错误:如果输入不是一个有效的数字,这些方法会返回
NaN
。但它们无法告诉我们失败的原因,比如是一个类型错误、溢出、还是非法字符等。parseInt("foo"); // NaN parseInt("Infinity"); // NaN
特殊的基数参数:
parseInt
还有一个可选的基数参数,用于指定待解析字符串中的数字是什么进制的。但这个参数很容易被忽略或者误解。parseInt("010"); // 8 parseInt("0x10"); // 16
更可靠的解析数字方法
ES12 提供了更可靠的方法来解决上述问题:BigInt
和 Number.parseFloat
。
BigInt
BigInt
是一个新的原始类型,用来表示任意精度的整数。它的实例可以通过在数字末尾加上 n
后缀来创建,也可以通过 BigInt()
函数来转换为 BigInt
类型。在解析一个数字字符串的时候,我们可以使用它的 BigInt()
函数来实现:
BigInt("100") // 100n
如果字符串不是一个有效的数字,这个方法会抛出一个 SyntaxError
异常:
BigInt("foo") // Uncaught SyntaxError: Cannot convert foo to a BigInt
通过检查抛出的异常,我们可以得知转换失败的原因。
Number.parseFloat
Number.parseFloat
和 parseFloat
的行为类似,但它对输入的字符串做了更严格的检查。
输入必须是严格的数字格式:
Number.parseFloat
只会解析完全符合数字格式的字符串,而忽略掉末尾的无效字符。Number.parseFloat("2.7 apples"); // 2.7 Number.parseFloat("$2.99"); // NaN
会检测错误:如果输入不是一个有效的数字,它会返回
NaN
,并抛出一个TypeError
异常。Number.parseFloat("foo"); // NaN, with TypeError: Not a Number Number.parseFloat("Infinity"); // NaN, with TypeError: Not a Number
通过检查抛出的异常,我们可以得知转换失败的原因。
不支持进制参数:
Number.parseFloat
没有进制参数,因此不会出现疑惑的解析结果。Number.parseFloat("010"); // 10 Number.parseFloat("0x10"); // 16
总结
ES12 中的更可靠的 Number Parsing 方法让我们能够更轻松地解析和转换数字字符串。使用 BigInt()
可以方便的将字符串转换为任意精度的整数,而 Number.parseFloat
不仅没有类型转换的陷阱,还会抛出更有意义的异常,让我们能够快速定位问题。
实现输入不可靠的数字解析时,可以优先考虑使用这些新的方法。当然,在遗留代码中的解析逻辑需要修改时,也可以替换成这些更可靠的方法。
示例代码
const input = "2.7 apples"; // 旧的解析方法 const oldParseInt = parseInt(input); // 2 const oldParseFloat = parseFloat(input); // 2.7 // 新的解析方法 const newBigInt = BigInt(input); // Uncaught SyntaxError: Cannot convert 2.7 apples to a BigInt const newParseFloat = Number.parseFloat(input); // 2.7, with TypeError: Not a Number
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65942c47eb4cecbf2d8b33f1