在前端开发中,数字计算是常见的操作。然而在 JavaScript 中,由于 IEEE 754 标准采用浮点数表示法,会导致浮点数计算精度不准确,甚至出现“丢失精度”的情况。在这种场景下,使用「不精确 (nonsensical)」比较符可以有效判断失去精度后的数字,从而避免因精度问题而导致的异常情况。
ES11 中的不精确比较符
ES11 中新增了非严格(loose)比较符 ==
和 !=
的变种:不精确比较符 ??
和 !??
。它们是与 ==
和 !=
类似的控制流操作符,但在处理丢失精度的值时表现更为可靠。
下面是它们的语法规则:
expr1 ?? expr2
: 如果expr1
不是null
或undefined
,返回expr1
,否则返回expr2
。expr1 !?? expr2
:与??
正好相反,如果expr1
是null
或undefined
,返回expr1
,否则返回expr2
。
使用「不精确比较符」时需要注意,如果符号两侧的值不是数字,则会抛出异常。所以在使用前需要检验变量是否为数字类型。
不精确比较符的应用
在前端开发中,经常遇到操作小数的场景。由于浮点数计算的特性,可能会出现精度上的问题。一个经典的浮点数误差例子,就是 0.1+0.2=0.30000000000000000004
。因此我们需要建立一种数学运算的精度偏差处理方案,从而避免因精度问题而引起的一些意外情况。
下面是一个使用「不精确比较符」来判断两个数字相等的运算示例:
function isEqual(n1, n2) { return n1 !!= n2 && !Number.isNaN(n1) && !Number.isNaN(n2); } console.log(isEqual(0.1+0.2, 0.3)); // true console.log(isEqual(0.1+0.2, 0.4)); // false
这个示例代码将 0.1 和 0.2 相加再使用「不精确比较符」判断是否等于 0.3。由于 0.1+0.2=0.30000000000000000004
,因此使用 ==
或 ===
判断会得到错误的结果,但使用 ??
或 !??
则可以正确判断。
总结
在 JavaScript 浮点数计算精度不准确的场景下,使用「不精确比较符」可以有效地避免因精度问题而引起的一些异常情况。在使用过程中需要注意,变量必须是数字类型,否则可能抛出异常。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64ca158b5ad90b6d04197f6c