JavaScript で最大値を求める Math.max のような引数に配列を与えられるスプレッド構文と少しの注意点のメモ

JavaScript で最大値を求める Math.max のような引数に配列を与えられるスプレッド構文と少しの注意点のメモ

JavaScript で最大値を求める Math.max のような引数に配列を与えられるスプレッド構文と少しの注意点のメモです。

背景

最大値を求める Math.max のような引数で 2 つの値ではなく、配列の形で複数の値を与えたい時があります。

Math.max() - JavaScript | MDN

こちらにあるとおりで、スプレッド構文を使うと、

const arr = [1, 2, 3];
const max = Math.max(...arr);

このような形で、配列の形で複数の値を与えることができます。とても便利。

私も以前から見かけてたのですが、最近馴染んで、使用頻度が高くなってきました。

注意点があるようだ

ところが、Math.max のドキュメントでこんな言及があります。

しかし、スプレッド構文の (...) と apply のどちらも、配列に膨大な要素があった場合は、配列の要素を関数の引数として渡そうとするため、失敗したり、誤った結果を返したりすることがあります。詳しくは apply を組み込み関数と共に利用するを参照してください。 reduce の方法はこの問題が発生しません。

自分は 100 とか 1000 くらいの配列数がせいぜいなので、いあっまで遭遇したことはないのですが「え?膨大って????」という疑問が出てきました。

ChatGPT にも聞きましたが、なかなか芯をとらえたものが出てこないですが、

スプレッド構文 - JavaScript | MDN

こちらを見る限り、

スプレッド (...) 構文を使うと、配列式や文字列などの反復可能オブジェクトを、0 個以上の引数(関数呼び出しの場合)や要素(配列リテラルの場合)を目的の場所に展開することができます。

ということで、

const arr = [1, 2, 3];
const max = Math.max(...arr);

というのは、

const max = Math.max(1, 2, 3);

と展開されるわけで、この展開される限界数がネックになりそうです。

Math.max() にスプレッド構文で大きな配列を渡すとエラーになる恐れがある

Math.max() は、引数に渡された数値のうち最大のものを返す JavaScript の組み込み関数です。この関数は任意の数の引数を受け取るので、配列最大値を求めたい場合にはスプレッド構文で展開して渡す使い方が一般的です。しかし、引数の数が多すぎるとエラーになることがあります。

こちらの方も触れられてました。

この例では、Array.from() メソッドを使って 100 万個の数値を持つ配列を生成し、Math.max() に渡しています。しかし、引数が多すぎるためスタックオーバーフローが発生し、エラーがスローされています。

実際のコードも交えつつ、こんな素晴らしい実験をされていました。わかりやすい。

ということで、膨大というのは 100 や 1000 程度の話ではなさそうです。実際、私も使っていても、その程度の数では遭遇したことはないですし。

ただ、データベースの値を一気に配列で受けて最大値を得る、、、なんていう使い方だと「膨大」に遭遇しそうです。

どんなエラーが出るかもわかったので、そのときは、おとなしく reduce 方式にしようと思います。