阅读 539

[译] 在 JavaScript 中为什么 Math.max() 会比 Math.min() 小?

在 JavaScript 中为什么 Math.max() 会比 Math.min() 小?

Math.max() < Math.min() === true

惊讶吗?这就是为什么在不传递参数时,JavaScript 中取最大值函数小于取最小值函数的原因。

你知道在 JavaScript 中 Math.max() 不传参数返回的值要比 Math.min() 不传参数返回的值小的原因吗?

console.log(Math.max() < Math.min()) // true
复制代码

为什么会这样?让我们检查一下这个函数返回了什么:

console.log(Math.max()) // -Infinity
复制代码

很奇怪 —— 在 JavaScript 中 Infinity 实际上是数值最大的数,还有 Number.MAX_VALUENumber.MAX_SAFE_INTEGER.

那么 Math.min() 不带参数会返回什么呢?

console.log(Math.min()) // Infinity
复制代码

又一次,我们所期待的恰恰相反 —— 在 JavaScript 中 -Infinity 应该是数值最小的数,还有 Number.MIN_VALUE.

那么为什么 Math.min()Math.max() 实际的值和我们预期的会相反呢?

答案就藏在 MDN Docs

-Infinity 是初始比较项,因为几乎所有其他值都比它更大,这就是为什么没有给出参数的时候,会返回 -Infinity

如果至少有一个参数让其不能转换为一个数字,那么结果将是 NaN.” — Math.max() 在 MDN 中的文档

当然了! Math.max() 只是一个基于 for 循环的参数实现 (看看 Chrome V8 的实现)。

因此,Math.max() 会从 -Infinity 开始搜索,因为任何其他数字都比 -Infinity 大。

同样,Math.min() 会从 Infinity 开始搜索:

“如果没有传任何参数,那么将返回 Infinity

如果至少有一个参数不能转换为数字,那么将返回 NaN。” — MDN Docs for Math.min()

ECMAScript 规范 中对于 Math.max()Math.min()也指出,通过这些函数,+0 被认为大于 -0

console.log(Math.max(+0,-0)) // 0
console.log(Math.min(+0,-0)) // -0
console.log(+0 > -0) // false
console.log(+0 > -0) // false
console.log(+0 === -0) // true
console.log(+0 == -0) // true
console.log(Object.is(+0,-0)) // false
复制代码

这种行为不同于 > 大于和 \< 小于运算符,后者认为 -0 负零 等于 +0 正零。

从技术上讲,根据 ===== 相等运算符 -0 负零是和 0 正零相等的,而不是根据 Object.is()

因此,在某种意义上,Math.max()Math.min()-0 负零单纯的实现更加地优雅(参见V8代码中的第 96-99 行)。

喜欢这篇文章吗? 那么你会喜欢我的这篇文章:用最快的方式在 JavaScript 数组中找到最大和最小值 —— 我展示了一个使用 Math.max()Math.min() 的方法,比使用 ... 扩展运算符 更快: 用最快的方法在 JavaScript 中查找数组中最小值和最大值

现在你已经了解了 Math.max()Math.min() 的所有特性!

Happy Coding! 😊💻😉🔥🙃

如果发现译文存在错误或其他需要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可获得相应奖励积分。文章开头的 本文永久链接 即为本文在 GitHub 上的 MarkDown 链接。


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏