経緯
「JavaScriptのMathオブジェクトのsumメソッドについて現役エンジニアが解説」というタイトルの記事が出てきて、最近だと Math.sum() 実装されてるんか。へー。って思って読んだら「Math.sum() はないので自分で実装しましょう」という内容でプログラミングスクール滅べと思った。
これ、検索して読みましたが、任意個数の引数を合計するメソッドと思いきや、単にa+bを返すメソッドだったので、「恥を知れ」と思いました
JavaScript、Array.prototype.reduceがあるから、
nums.reduce((x, y) => x + y)
でええんちゃうの…?
元ネタと思われるコード
多分、これ。
JavaScriptのMathオブジェクトのsumメソッドについて現役エンジニアが解説【初心者向け】
var sum = function (a, b) {
return a + b;
;
}
console.log(sum(1, 2));
現役ハッカー(略)が解説
そのコードは
1 + 2
と等価なので、完全にフールである。
JavaScriptにはMath.sum()
は存在しない。
だが、そもそもそのようなものは必要ないし、そもそもsum関数があるとして、一般的にはイテレータ操作だから、Math
よりはArray
やEnumerator
に属するべきものだ。
私が言及した
.reduce((x, y) => x + y) nums
は有効なコードであであり、関数の自作などせずとも目的を達成できる。
Array.prototype.reduce()
はRubyで言うところのEnumberable#inject
のようなものである。
コールバック関数を受け取り、Array.prototype.forEach
のようなイテレータ操作メソッドが追加された過程で追加されたものである。
Mozilla Firefox 3からサポートされた。
コールバック関数は2つの引数を取り、(最後の戻り値, 次の値)
である。
[1, 2, 3].reduce()
だとしたら、まずひとつ目の値である1
はコールバックの評価をされず戻り値という扱いになる。
そして、1回目のコールバック関数は(1, 2)
という引数で起動される。
2回目のコールバック関数のひとつ目の引数は、この1回目のコールバック関数の戻り値となり、2つ目の引数は3
となる。
() =>
という書き方は、最近の関数の書き方だ。
まず、(arg) => {code}
というアロー関数という形式がある。
引数がひとつである場合、カッコは省略でき、arg => {code}
と書くことができる。
さらに新しい書き方としてcode
を囲むブレースを省略できる。
これは単一の式文からなる場合に省略でき、省略した場合return
が自動的に行われる。
そのため、
, y) => x + y (x
は
, y) => { return x + y } (x
と等価である。
これらを組み合わせて、
.reduce((x, y) => x + y) nums
が適切な答えとなる。
なお、この形式のアロー関数がサポートされたのはかなり最近(Firefox 52/Chrome 58)なので、ブラウザ互換性を重視するならば、
.reduce(function(x, y) { return x + y}) nums
となる。