先记住这个答案
JavaScript 不会在除以零时抛错,而是返回 Infinity 或 -Infinity。这两个值都是合法的 number 类型,可以参与比较和算术。Infinity 大于任何有限数,-Infinity 小于任何有限数。但两个无穷大之间做不确定的运算(比如 Infinity - Infinity)会得到 NaN。检测一个数是不是有限的,用 Number.isFinite()。
- 除以正负零可得到正负无穷大
0 / 0得NaN,不是InfinityInfinity - Infinity是NaNNumber.isFinite不做类型转换
哪些运算会产生无穷大
最直接的方式是正数除以 0,得到 Infinity;负数除以 0,得到 -Infinity。但 0 / 0 是 NaN,因为零除以零在数学上没有确定结果。除了除法,数值溢出也会产生 Infinity。
Infinity 的方式JavaScriptconsole.log(1 / 0);
console.log(-1 / 0);
console.log(0 / 0);
console.log(Number.MAX_VALUE * 2);
console.log(1e309);
console.log(typeof Infinity);查看输出与解释
Infinity
-Infinity
NaN
Infinity
Infinity
numberNumber.MAX_VALUE 大约是 1.8e308,乘以 2 就超出双精度浮点数的表示范围,溢出到 Infinity。同理 1e309 也超出了上限。typeof Infinity 返回 "number",它确实是一个数字值,只是代表无穷大。
无穷大参与算术的规则
Infinity 参与加减乘除时,大部分情况符合数学直觉:任何有限数加上 Infinity 还是 Infinity,Infinity 乘以负数变成 -Infinity。但有几种运算的结果是 NaN,因为数学上它们是不确定的。
console.log(Infinity + 100);
console.log(Infinity * -1);
console.log(Infinity / Infinity);
console.log(Infinity - Infinity);
console.log(Infinity + Infinity);
console.log(Infinity > 1e308);查看输出与解释
Infinity
-Infinity
NaN
NaN
Infinity
trueInfinity / Infinity 和 Infinity - Infinity 都是 NaN,因为无穷大比无穷大或无穷大减无穷大没有确定的数学结果。但 Infinity + Infinity 仍然是 Infinity,因为正无穷加正无穷在数学上是确定的。
检测一个值是不是有限数,推荐用 Number.isFinite()。它不做类型转换,只对真正的有限数字返回 true。全局的 isFinite() 会先把参数转成数字,isFinite("123") 返回 true,容易误导。
容易答错的地方
- 以为
0 / 0是Infinity 0 / 0不是Infinity,是NaN。只有非零数除以零才产生无穷大。这个区分在数学上也是合理的——零除以零是不定式,没有确定结果。- 以为
JSON.stringify(Infinity)会输出"Infinity" JSON.stringify(Infinity)输出的是null,因为 JSON 规范不支持无穷大。JSON.parse之后拿到的是null,原来的Infinity信息就丢了。如果接口需要传递无穷大,得自己约定协议,比如用特定字符串表示。
面试官还会怎么问?
Number.isFinite() 和全局 isFinite() 有什么区别?
Number.isFinite() 不做类型转换,参数不是 number 类型直接返回 false。全局 isFinite() 会先调用 Number() 转换,所以 isFinite("42") 返回 true,而 Number.isFinite("42") 返回 false。推荐用 Number.isFinite()。
Math.max() 不传参数返回什么?
返回 -Infinity。Math.min() 不传参数返回 Infinity。这看起来反直觉,但是有道理的:Math.max() 需要一个初始值,这个初始值要比任何可能的参数都小,才能被第一个参数覆盖,所以用 -Infinity。
怎么判断一个计算结果是正无穷还是负无穷?
直接用 === Infinity 或 === -Infinity 比较。也可以用 value > 0 && !Number.isFinite(value) 判断正无穷,但直接比较更简洁。Object.is 也能区分,但对于 Infinity 和 -Infinity 来说,=== 已经足够了,因为它们本身就是不同的值。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。