kvzbpa
Last Updated: September 28, 2018
·
844.8K
· afshinm

Don't use Array.forEach, use for() instead

Array.ForEach is about 95% slower than for() in for each for Arrays in JavaScript.

So, don't use:

arr.forEach(function (item) {
  someFn(item);
})

Use:

for (var i = 0, len = arr.length; i < len; i++) {
  someFn(arr[i]);
}

See this performance test online: http://jsperf.com/fast-array-foreach

49 Responses
Add your response

2110

In first example you can write something like this:

arr.forEach(someFn);

It's really useful.
In some cases you'll realy need to use forEach method. For example, if you need a closure for your loop.

elements.forEach(function(element){
  var attribute = element.getAttribute('data-attr');
  element.onclick = function(){
    alert(attribute);
  };
});
over 1 year ago ·
2112

@avenger7x Sure, yes. I forgot to mention when we need to use forEach but in some cases that I saw in applications, it uses incorrectly and only because it's easy-to-use.

over 1 year ago ·
2116

for loops are really annoying when you're trying to build something complex, maintainability becomes harder, I think that there is a third solution http://mlb.tl/LIFL which is faster than forEach and still keeps a nice FP & OO coding-style.

Otherwise I agree that for small scripts, a good old for loop can be accurate.

over 1 year ago ·
2119

@mlb Hey Thanks, good alternative solution.

over 1 year ago ·
5778

Hello!
This is faster:
Array.prototype.forEach2=function(a){
var l=this.length;
for(var i=0;i<l;i++)a(this[i],i)
}
http://jsperf.com/sdngjkn

over 1 year ago ·
6538

One other reason not to use Array.forEach is that it is not supported by IE8.

over 1 year ago ·
13714

lol. Since when IE8 is supposed to rule our choices ?
The fact that IE8 doesn't support Array.forEach really means this bowser is deep shit, that's all ! ;)

over 1 year ago ·
14871

Micro premature optimization is the root of so many evils. The rule is don't use it in a tight loop. Anywhere else, it will never matter. DOM maintenance is where you should optimize.

over 1 year ago ·
17942

One other reason to use Array.forEach is that it is not supported by IE8. ;-)

over 1 year ago ·
19298

JSPerf is a double-edged sword, you really need to start thinking about what it does and how it can return confusing results. Furthermore, 95% slower is practically NOTHING in terms of JS performances. What you need to focus on is Draw counts (if you are working the canvas) or plain DOM updates. Check out this great speak on micro-optimizations: https://www.youtube.com/watch?v=65-RbBwZQdU

over 1 year ago ·
20316

@william_malo, your test is misleading. Your vanilla javascript for loop was not actually calling the function, but merely running the guts of the function within the loop. Here is a more accurate test: http://jsperf.com/sdngjkn/19

over 1 year ago ·
20907

In your test and in ntg's, forEach was the fastest in Firefox 38 on 64-bit Linux (Slackware).

over 1 year ago ·
23831

for() loop runs in sync mode, it is too bad for a js application, if you are programming a js app, you'd better use Array.forEach, it runs in async mode, else you won'd go far.

over 1 year ago ·
26560
27039

There is a difference between for and forEach. for will local reassign variable for every run, while forEach will create new variable. Example:

var links = document.getElementsByTagName('a');
for(var i = 0; i < links.length; i++) {
  var element = links[i];
  element.addEventListener('click', function () {
    alert(element.innerText); // you think it will be element you clicked on? It will be last element in array
  });
}
over 1 year ago ·
27355

The main reason for using for loops over Array.forEach is that you cannot break the latter. Other than that, I prefer the Array.forEach semantics. If performance degradation is really noticeable I will take into account your suggestion. Thank you.

over 1 year ago ·
27419

Note that this is only for ES5 in a browser. If you've got ES6 then you'll want to use for ( X of arr ) { ... }.

over 1 year ago ·
27469

Don't forget to weigh performance against legibility/maintainability. As juanmendes said, premature optimization can yield problems.

over 1 year ago ·
27609

Personal opinion, here, but I think there is a larger issue being overlooked here.

The purpose of either for() or .forEach() is presumably to actually do something with each of the array elements. Simply comparing the two method's speed, divorced from actually doing anything inside their loops is a rather meaningless comparison. The work being done inside the loop of each method is going to dwarf the execution speed of the looping mechanism itself, almost to the point of irrelevance.

By the time you add a simple database lookup, and a printf(), 99.9% of the time is going to be spent on the work, and 0.1% of the time is consumed by the actual looping mechanism overhead.

If you had a million array elements to iterate, and nothing more than "i++;" inside the loop, then yeah, maybe the benefits of for() over .forEach() might be worth considering. But this is rarely the case.

over 1 year ago ·
27822

Or use lodash's forEach implementation which is about as performant as the plain for loop.

over 1 year ago ·
28224

Thanks for sharing a useful information.

over 1 year ago ·
28239

This is a terrible tip and I'll explain why.

  • Javascript has functions as a first class citizen. each/forEach is only slower because it creates a lexical scope around each loop iteration. In practice this is usually what you want.
  • 9/10 times you really want .map. You're probably looping in order to transform data.
  • loops favor side effects over pure functions. this means reaching into other scopes, and unpredictability. .map and functional approaches are objectively easier to test
  • if you have code where you are iterating so much that a for loop performance over map is so significant, you probably need to download lodash anyways.
  • if you really, really really must loop. (note: you probably don't) do NOT evaluate length in the iterator!! that gets called every time!
  • and if you REALLY must loop a while with a -- decrementor is actually even faster. Following the guidelines of asm.js are even better than that..Again, you probably do not need this in everyday practice, the tradeoof for testability and readability is not usually worth it.

Don't use loops. Don't use each. Use pure functions with no side effects. Map, filter, reduce.

over 1 year ago ·
28273

In My tests performance for forEach, is similar to (for(;;) loops, in smaller arrays, forEach is even faster, (for of) is the slowest unfortunately

over 1 year ago ·
28324

I would use Array.forEach over for() any day.

over 1 year ago ·
28335

@the-simian, caching array.length outside of the iterator and reverse/decrementing loops are no longer necessarily faster. Reasonably modern JavaScript engines automatically optimise established patterns, such as forward loops and evaluating length - writing them in an "optimised way" prematurely simply adds confusion.

over 1 year ago ·
28355

I also make a compare test with native loop, native foreach, lodash foreach and underscoure foreach.
https://jsperf.com/for-loop-test-more
FYR

over 1 year ago ·
28370

for loops are really annoying when you're trying to build something complex, maintainability becomes harder, I think that there is a third solution http://gastrichealthtablet.org http://triflexcapsule.com

over 1 year ago ·
28376

Premature optimization!!!

over 1 year ago ·
28501

Thanks

over 1 year ago ·
28545

Don't use for(), because it is ugly

over 1 year ago ·
28612

thank you for allowing us to share information.
hopefully we are all in the given smoothness
http://www.rajanyaobatherbal.com/

over 1 year ago ·
28651

I think the description here is incorrect. It is not 95% slower. That would mean it runs 1/20 of the speed of the other. It is "...95% as fast..." or "...5% slower..." (which is the terminology used in the test link).

over 1 year ago ·
28720

This appears to no longer be true. The jsperf link showed for/forEach take about the same time in FF51.

over 1 year ago ·
29008

This is valid only if you experience real performance problems. If not, it is premature optimisation at its best (or worst :) ). Main question here - what is more expensive to the company: code, running some miliseconds or microseconds slower, or the developers, spending minutes => hours => days reading it, trying to figure what all these loops all over the project actually do. :) Remember, we spend more time reading code, than writing it.
Actually, the example makes me want rewrite it to use map or reduce, instead of forEach (depending of what someFn does), but that's another story.

over 1 year ago ·
29196

How about WHILE () {}??

over 1 year ago ·
29294

@avenger7x you could still have a closure with a for loop if you make the function outside the for loop

over 1 year ago ·
29325

@the-simian I agree with you so much!

over 1 year ago ·
29375

Do yourself a favor as a coder and DO NOT follow this "tip". Instead, read the-simian's comment.
Rule #1 in coding: do not attempt premature optimization, favor code clarity and simplicity.

over 1 year ago ·
29389

joanllenas, you don't need a break in .forEach(). Because you use it as the name says — when you want your function to be executed against each element of array. If you want it to be executed only again some of them, there's a method called exactly like that — .some() (see Array.prototype.some).

12 months ago ·
29457

Thank you for this share

11 months ago ·
29501

One will step through each iteration synchronously; the other will run each function as separate in the event queue:

For example:
for (let i = 0; i < arr.length; i++) { setTimeout(() => { console.log(arr[i]); }, 100); }
will give a different result than
arr.forEach((ele) => { setTimeout(() => { console.log(ele); }; };

10 months ago ·
29659

If considering modern browsers (with full ES6 support) , my favorite is "for of" loop. Like
for(let i of j){
//do something
}

8 months ago ·
29677

What about this test? What is the difference I wonder.

https://jsperf.com/testing-foreach-vs-for-loop

8 months ago ·
29770

you can't use for loop in async javascript

7 months ago ·
29823

Great tip. I love simplicity and nothing beats it like native, well known language constructs. But, if what dillon-bostwick claims is true (all evidence I see is to the contrary), then the foreach does have that in its favor.

6 months ago ·
29902

The only reason a for loop is faster is that the browsers have optimized it. Once we start using methods like forEach, map, reduce and filter, the browsers will optimize for those as well. Plus, for loops are not asynchronous.

5 months ago ·
29903

Damn, this is just another confirmation of why I recently switched to Firefox...

Chrome:
Array.forEach - 48,912
For - 504,695

Firefox:
Array.forEach - 1,024,928
For - 1,127,704

But of course, one should implement according to what the most popular browser demands...

5 months ago ·
30123

Another way is to use closure.
var links = document.getElementsByTagName('a'); for (var i = 0; i < links.length; i++) { (function(element) { element.addEventListener('click', function(ev) { ev.preventDefault(); alert(element.innerText); }); })(links[i]); }
Benchmark

4 months ago ·
30135

this is rarely the case.

4 months ago ·