探究在 JavaScript 中,Math.max() 和 Math.min() 在不填入参数的情况下为什么返回 -INFINITY 与 INFINITY

探究在 JavaScript 中,Math.max() 和 Math.min() 在不填入参数的情况下为什么返回 -INFINITY 与 INFINITY

在一张被广为流传的 JavaScript Meme(梗图)中,我们可以看到这么一个例子,Math.max() 在不填入的参数的情况下返回了 -INFINITYMath.min() 在同样的情况下返回了 INFINITY

明明是一个求最大数的方法,却返回了用于表示最小数的 -INFINITY,这让我感觉到有点匪夷所思。

想探寻为什么其实很简单,标准库的代码其实也是人写的,只要去找一下 Math.max()Math.min() 的具体实现方式就能知道了。

以下文字内容建议配合附加的代码配合观看

Math.max() 为例,在 Chrome 浏览器所使用的 JavaScript 引擎,也就是 V8 引擎的 Math 库的源码中,我们可以看到当所填入的参数个数 2 时,则使用 if 语句既可以实现返回最大值的功能。但当填入的参数个数不为 2 时,则是使用 for 循环遍历所有的参数,并使用一个变量 r 存储参数中最小的值。而变量 r 的在一开始被赋值为 -INFINITY,如果参数的个数为 0 时,则用于找出最小值的 for 语句块则不会被执行,所以直接返回了 -Infinity

Math.min() 其实也是一个思路,这里就不多讲了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// ECMA 262 - 15.8.2.11
function MathMax(arg1, arg2) { // length == 2
var length = %_ArgumentsLength();
// 如果参数的个数为2,直接使用if语句判断结果
if (length == 2) {
arg1 = TO_NUMBER_INLINE(arg1);
arg2 = TO_NUMBER_INLINE(arg2);
if (arg2 > arg1) return arg2;
if (arg1 > arg2) return arg1;
if (arg1 == arg2) {
// 如果两个参数都为0(如参数填入了0与-0),优先返回-0
// Make sure -0 is considered less than +0.
return (arg1 === 0 && %_IsMinusZero(arg1)) ? arg2 : arg1;
}
// All comparisons failed, one of the arguments must be NaN.
return NAN;
}
// 如果参数的个数不为2,比如填入了0个、1个甚至多个参数时
// 通过遍历的方式找出最小值,并用变量r进行存储
var r = -INFINITY;
// 如果参数个数为0,这下面的for语句块则不会执行
for (var i = 0; i < length; i++) {
var n = %_Arguments(i);
if (!IS_NUMBER(n)) n = NonNumberToNumber(n);
// Make sure +0 is considered greater than -0.
if (NUMBER_IS_NAN(n) || n > r || (r === 0 && n === 0 && %_IsMinusZero(r))) {
r = n;
}
}
return r;
}

// ECMA 262 - 15.8.2.12
function MathMin(arg1, arg2) { // length == 2
var length = %_ArgumentsLength();
if (length == 2) {
arg1 = TO_NUMBER_INLINE(arg1);
arg2 = TO_NUMBER_INLINE(arg2);
if (arg2 > arg1) return arg1;
if (arg1 > arg2) return arg2;
if (arg1 == arg2) {
// Make sure -0 is considered less than +0.
return (arg1 === 0 && %_IsMinusZero(arg1)) ? arg1 : arg2;
}
// All comparisons failed, one of the arguments must be NaN.
return NAN;
}
var r = INFINITY;
for (var i = 0; i < length; i++) {
var n = %_Arguments(i);
if (!IS_NUMBER(n)) n = NonNumberToNumber(n);
// Make sure -0 is considered less than +0.
if (NUMBER_IS_NAN(n) || n < r || (r === 0 && n === 0 && %_IsMinusZero(n))) {
r = n;
}
}
return r;
}

探究在 JavaScript 中,Math.max() 和 Math.min() 在不填入参数的情况下为什么返回 -INFINITY 与 INFINITY

http://pinkchampagne17.github.io/blog/2021/09/29/在JavaScript中,Math.max()和Math.min()在不填入参数的情况下为什么返回-INFINITY与INFINITY/

作者

PinkChampagne17

发布于

2021-09-29

更新于

2021-09-29

许可协议

 CC BY-NC-SA 4.0