Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
Tags
(+1)

The difference is that the forEach closure is writing to a bound variable. If you do the same thing in the for loop, it gets slow, too:

{   
    console.time('for 1')    
    let sum = 0    
    for (let i = 0; i < data.length; i++) {        
        sum += data[i] * data[i];    
    }    
    console.timeEnd('for 1')
}
{    
    console.time('for 2')    
    let sum = 0    
    for (let i = 0; i < data.length; i++) {        
        sum += data[i] * data[i];    
    }    
    console.timeEnd('for 2')
    
    function foo() { sum = 1; } // create a closure bound to sum; note we never even call this
}

Result:

for 1:  31.060ms
for 2: 789.796ms

Note that the loops are identical. The only difference is that in the second block, we've bound sum to a closure. That makes writing to it much more expensive.

That's why your forEach loop is so much slower. It's the only code in your example that writes to a bound variable inside the loop. You'd get the same performance degradation in any of your other looping constructs if you do the same thing.