3

I can either do,

var arr = [];

arr.forEach(function(i) {

     i;
});

for (var i = 0, length = arr.length; i < length; ++i) {

     arr[i];
}

When should I use one over the other, is there performance differences?

user2251919
  • 665
  • 2
  • 11
  • 23
  • 2
    `forEach` is slower, but it creates a scope for each iteration, which you manually have to do with a normal `for` (if you need one)...and also lets you set the value of `this` in the callback (with its second parameter). It's also not supported in **all** browsers: http://kangax.github.io/es5-compat-table/#Array.prototype.forEach . `forEach` also doesn't loop over empty items. Read more here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach - it includes a polyfill for browsers that don't support it – Ian Jun 04 '13 at 18:05
  • This partially answers your question: http://stackoverflow.com/questions/9329446/for-each-in-a-array-how-to-do-that-in-javascript – vasanth Jun 04 '13 at 18:05
  • 1
    To answer the performance question, create a performance test on http://jsperf.com/ with 50,000 values in your array. Or executing 50,000 loops. – LarsH Jun 04 '13 at 18:05
  • `forEach` is ECMAScript 5 -> compatibility – Moritz Roessler Jun 04 '13 at 18:06
  • Heres a performance test, results in the console: http://jsfiddle.net/ssSt5/2/ – Tim Baas Jun 04 '13 at 18:13
  • 1
    @Tim I see that one snippet has live output while the other has not - that might change the time required for the iteration. You know - they are lies, damn lies, and benchmarks. :) – Zsolt Szilagyi Jun 04 '13 at 18:22

1 Answers1

10

You use foreach whenever :

  • your array is associtive or has gaps, i.e. you cannot reach every element by an incremented number (1,2,5, 'x', -7)
  • you need to iterate in exactly the same order as they appear in the array. (e.g. 2,1,3)
  • you want to be sure not the get into an endless loop

The last point is the main difference: foreach works on a copy, so even if you alter the elements, the array remains intact and can be iterated without defects.

That copy makes foreach somewhat slower than for, since it has to copy data. Keep in mind that some old or rare browsers don´t supports foreach, but they do support "for". Unless your array is really big (10.000 + items), ignore the speed difference. It´s in the milliseconds.

You use for whenever

  • you want an easy way to aler the array you are moving on
  • you want specific sequences, e.g. for ($i=100; $i < 1000; $i += 5) resulting in 100, 105, 110...
Zsolt Szilagyi
  • 4,741
  • 4
  • 28
  • 44
  • I have built a game engine and am trying to cram every little bit of speed I can. I guess it can only be a good thing to change them to for loops as it is faster and makes my engine more compatible, right? – user2251919 Jun 04 '13 at 18:11
  • @user2251919 if your array is gaplessly numbered and you have the knowledge to avoid accidental endless loops, yes. How ever, do not overestimate the difference. :) – Zsolt Szilagyi Jun 04 '13 at 18:13
  • Okay thanks, I will keep it in mind, I think I will leave it for now, but it is still a good thing to know :) – user2251919 Jun 04 '13 at 18:15
  • 1
    *"your array is associtive"*: You should **never** use non-numerical properties with arrays. They won't be considered as array elements, not even by `forEach`. Negative indexes are not considered either. *" foreach works on a copy"*: That's incorrect (or at least it's an implementation detail). Only the range of the elements is fixed. If you modify an value of the array before it was iterated over, the callback gets the new value. See http://es5.github.io/#x15.4.4.18. Where do you have the information that it works on a copy? – Felix Kling Jun 04 '13 at 18:31
  • 1
    *"you need to iterate in exactly the same order as they appear in the array"* You can use a `for` loop for that as well. Overall I think your answer contains some inaccurate information, especially about the copy thing. The specification is pretty clear about how modifications should be handled. – Felix Kling Jun 04 '13 at 18:38