Math.max()
は与えられた複数の数値のうち最大の数を返します。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math/max
引数を与えないと -Infinity
という最小の数値を返すのが意外というのが最近ちょっと話題になりました。
> Math.max()
<- -Infinity
配列のevery
メソッドは、配列要素のすべてで条件式が成立する場合にtrueとなります。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/every
これも、空の配列で呼ぶと条件式が一回も成立していないのにtrueを返すのが意外だと話題です。
> [].every(x => false)
<- true
これらは、別に「JavaScriptの奇妙な仕様」ではありません。
集合演算のできるほぼすべての言語が同様の仕様となっています。JavaのStream.allMatch()
だってC# LINQの.All()
だってそう。
これらの仕様は「中立元を返している」のだと理解すると腹に落とすことができると思います。
中立元
どんな数に1をかけても同じ数です。
どんな数に0を足しても同じ数です。
これらのことを「かけ算の中立元は1だ」「足し算の中立元は0だ」と表現します。演算しても元の数と同じ結果になるような数のことを、その演算の中立元だと言うわけです。
さて、数のゼロ乗は1になることを中学で習うと思いますが、納得のいかなかった方、いらっしゃいませんか。
- 33は3×3×3
- 32は3×3
- 31は3
- 30は、3を一個もかけ合わさないってどういうこと⋯? “虚無”⋯? 仕方ない、先生が1と言ったから1だと覚えよう⋯
みたいになりそうじゃないですか。ところが1という中立元があると、以下のようにすんなり書けるわけです。(単にすんなり書けるというだけでなく、33は32の3倍、32は31の3倍、と同様に31は30の3倍が成立してキレイな関係が続くようにもなり美しくなります)
- 33は1×3×3×3
- 32は1×3×3
- 31は1×3
- 30は1
同様に0の階乗が1になることもすんなり納得できるはず。
Math.max()
も同じです。「大きい方」という演算において中立元は「無限小」ですから
-
Math.max(a, b)
は-Infinity
とa
とb
のうち最大の数 -
Math.max(a)
は-Infinity
とa
のうち最大の数 (→a
) -
Math.max()
は-Infinity
のうち最大の数 (→-Infinity
)
.every
、すべての論理値のANDをとるということですから、AND演算の中立元 true を使って
-
[a, b].every(cond)
はtrue
&&cond(a)
&&cond(b)
-
[a].every(cond)
はtrue
&&cond(a)
-
[].every(cond)
はtrue
となりますという次第です。
「繰り返し演算は、対象がゼロ個だと中立元が答えになる」
プログラミングでもそれ以外の分野でも役に立つことがときどきあるので是非覚えておいてください。