昨天心血來潮寫了一篇文章:為什么Math.min() 比 Math.max() 大晨川?
為什么很多人會有這種疑惑证九,是因為犯了想當然的錯誤——望文生義。Math.min()
作為一個函數(shù)共虑,返回的并不是最小值愧怜;同理 Math.max()
返回的也不是最大值。他們返回的是參數(shù)的最大值和最小值妈拌,而我們卻沒有傳遞任何參數(shù)拥坛。
javascript 中數(shù)值的最大值和最小值常量分別是 Number.MAX_VALUE
和 Number.MIN_VALUE
,在我電腦 V8 的運行結(jié)果是 1.7976931348623157e+308
和 5e-324
。
這里也有一個坑渴逻,那就是 MIN_VALUE
并不是最小的數(shù)疾党,而是絕對值最小的數(shù),它是一個正數(shù)惨奕。而 Math.min()
的返回值比 Number.MAX_VALUE
還要大。
Math.min()
返回了 Infinity
竭钝,這個值對應了 Number.POSITIVE_INFINITY
常量梨撞。Math.max()
返回了 -Infinity
,這個值對應了 Number.NEGATIVE_INFINITY
常量香罐。
就像數(shù)學里面那樣卧波,正無窮和負無窮并不是確切的數(shù),只是集合里面的概念庇茫。我們可以使用 0 減去正無窮來得到負無窮:0 - Infinity = -Infinity港粱,或者通過 0 減去負無窮來得到正無窮:0 - (-Infinity) = Infinity。但是我們把正無窮和負無窮相加卻得不到 0旦签,事實上我們得到的是 NaN查坪。
當我們真正明白了 Math.min 和 Math.max 只是返回了所有參數(shù)的最大值,就很容易理解這個看似匪夷所思的結(jié)果了宁炫。
本來想查看 V8 的源碼偿曙,但是搜索了一圈,也只找到了幾個測試用例(文件: test/mjsunit/math-min-max.js):
assertEquals(Infinity, Math.min());
assertEquals(1, Math.min(1));
assertEquals(1, Math.min(1, 2));
assertEquals(1, Math.min(2, 1));
assertEquals(1, Math.min(1, 2, 3));
assertEquals(1, Math.min(3, 2, 1));
assertEquals(1, Math.min(2, 3, 1));
從此測試用例中可以看出羔巢,Math.min()
確實返回了 Infinity
望忆。繼續(xù)閱讀此測試用例還會發(fā)現(xiàn)更有意思的事:
assertEquals(-Infinity, Infinity / Math.min(-0, +0));
assertEquals(-Infinity, Infinity / Math.min(+0, -0));
assertEquals(-Infinity, Infinity / Math.min(+0, -0, 1));
對比下面的結(jié)果:
assertEquals(Infinity, Infinity / Math.max(-0, +0));
assertEquals(Infinity, Infinity / Math.max(+0, -0));
assertEquals(Infinity, Infinity / Math.max(+0, -0, -1));
也就是說在 Math.min
和 Math.max
進行數(shù)值比較(javascript不分整型和浮點型)時,負零是小于正零的竿秆。
-0启摄、+0、-Infinity幽钢、+Infinity歉备、NaN 這幾個概念就可以講上一天一夜了,篇幅有限就不展開講了搅吁,以后有時間再填坑威创。
言歸正傳,現(xiàn)在我們換個思路谎懦,試著從算法的角度去考慮最大值和最小值的問題肚豺。
我們?nèi)绾吻?N 個參數(shù)的最大值呢?為了描述簡單我們使用數(shù)組(感謝 @f2er前端百科)
var max = ___;
arr.forEach(function(n) {
if(n > max) {
max = n;
}
});
如果是填空題界拦,你會在空格處填什么呢吸申?如此想來,這個返回值就很合理了。
<del>本來以為是無參調(diào)用時返回了運算的幺元截碴,后來細琢磨梳侨,好像沒有什么關(guān)系,2333
對于運算集合 S 上的二元運算日丹,如果滿足 ax = xa = x走哺,則 a 是運算的幺元。加法運算的幺元是 0哲虾,因為 0+x = x+0 = x丙躏。乘法運算的幺元是 1,因為 1x = x1 = x束凑。但是我們定義函數(shù) add() 或者 mult() 函數(shù)晒旅,如果不傳遞參數(shù)時,返回幺元的話也是不合理的汪诉。</del>
完废恋。