Complementando, tem o detalhe (que pode ou não fazer diferença dependendo do caso) do reduce
ser mais lento, justamente porque precisa fazer várias chamadas de função (afinal, o parâmetro que vc passa para ele é uma função que é chamada para cada elemento).
Claro que para poucos arrays pequenos a diferença é insignificante, mas é algo a se considerar se estiver processando grandes volumes de dados. Fiz um teste simples no JSBench.ME, e também no Node usando o Benchmark.js:
var Benchmark = require('benchmark');
var suite = new Benchmark.Suite;
// cria um array bem grande, com números aleatórios entre 1 e 1000
var array = [];
for (var i = 0; i < 1000000; i++) {
array[i] = Math.floor(Math.random() * 1000);
}
suite
.add('for simples', function () {
let soma = 0;
for (var i = 0; i < array.length; i++) {
soma += array[i];
}
})
.add('for of', function () {
let soma = 0;
for (var n of array) {
soma += n;
}
})
.add('reduce', function () {
let soma = array.reduce((a, b) => a + b);
})
.on('complete', function () {
console.log('Fastest is ' + this.filter('fastest').map('name'));
})
.on('cycle', function (event) {
console.log(String(event.target));
})
.run({
'async': true
});
Basicamente, criei um array com 1 milhão de números e calculei a soma deles. Usei o for
"tradicional", o for..of
e o reduce
, e o resultado foi:
for simples x 1,434 ops/sec ±1.68% (90 runs sampled)
for of x 968 ops/sec ±1.18% (93 runs sampled)
reduce x 168 ops/sec ±0.84% (86 runs sampled)
Fastest is for simples
Os números representam a quantidade de operações por segundo ("ops/sec", ou seja, quanto maior, mais rápido). O for
tradicional foi cerca de 10 vezes mais rápido (fez quase 10 vezes mais operações por segundo que o reduce
). O for of
é um pouco mais lento, porque internamente usa o protocolo de iteradores que tem um custo um pouco maior, mas ainda sim é melhor que reduce
. Rodei mais algumas vezes, variando o tamanho do array, e os resultados foram similares. No JSBench.ME os resultados também foram parecidos (pode variar de acordo com o browser).
Como já dito, se forem poucos arrays pequenos, a diferença será imperceptível. Mas ainda tem os outros fatores já mencionados, de que um loop simples resolve melhor a maioria dos casos. Já vi muita gente forçando o uso de reduce
e deixando o código pior e mais confuso. Ele é útil sim, mas nem sempre é a solução mais adequada.