I think your test is not correct.
Take a look at this code. I'll use benchmark for testing and I'll extract the variables and the closure creation to the top of the script so they are not created in every test run, only just one.
const Benchmark = require('benchmark'); const suite = new Benchmark.Suite(); const data = []; for (let i = 0; i < 32000000; i++) { data.push(i * Math.random()); } let sum = 0; const adder = x => (sum += x * x); const reducer = (acc, curr) => acc + curr * curr; suite .add('standard for', function() { sum = 0; for (let i = 0; i < data.length; i++) { sum += data[i] * data[i]; } }) .add('for-of', function() { sum = 0; for (let datum of data) { sum += datum * datum; } }) .add('forEach', function() { sum = 0; data.forEach(adder); }) .add('reduce', function() { sum = data.reduce(reducer); }) .on('cycle', function(event) { console.log(String(event.target)); }) .on('complete', function() { console.log('Fastest is ' + this.filter('fastest').map('name')); }) .run({async: true});
The results are the following in node v10.15.1
standard for x 0.68 ops/sec ±1.68% (6 runs sampled) for-of x 0.64 ops/sec ±1.01% (6 runs sampled) forEach x 0.66 ops/sec ±1.07% (6 runs sampled) reduce x 1.72 ops/sec ±0.41% (9 runs sampled) Fastest is reduce
As you can see, there is almost no difference at all and the reduce version is clearly the fastest