The only for loop you will ever need *

* main contain hyperbole to take the mickey out of other blog posts

I am a very lazy person when it comes to typing. As I am doing so much of it I’d rather not type something I really don’t need. This is why I had an issue with “for” loops as you need to type them so often.

The classic way of looping through an array for example is a for loop with an iterator:

var arr = [1,2,3,4,5];
for( var i=0; i<arr.length; i++ ){
  alert( arr[i] );
}

This is however not a good plan for large arrays (like DOM trees) as the length attribute is read out every time the loop executes. You can avoid this in two ways. If it is for example irrelevant in which order you loop through the array you can use a reverse loop:

var arr = [1,2,3,4,5];
for( var i=arr.length - 1; i> -1; i — ) {
  alert( arr[i] );
}

If you really need to go through the array in the normal order then you need to use another variable to store the length and compare with that one.

var arr = [1,2,3,4,5];
for( var i=0,j=arr.length; i<j ; i++ ){
  alert( arr[i] );
}

The for loop also allows you to use the in keyword to make it easier:

for(i in arr ){
  alert(arr[i]);
}

However, there is also another trick if you don’t want to do this (for example if you don’t want to iterate through all but use a step of 2). The comparison inside the loop does not need to be the iterator but could be any comparison. As long as it is true, the loop gets executed, when it becomes false the loop ends. This allows you to simply check for the array element inside the loop itself which means you don’t need to read the length attribute at all:

var arr = [1,2,3,4,5];
for(var i=0; arr[i]; i++ ){
  alert( arr[i] );
}

There is however the issue of the truthy and falsy and type casting in JavaScript which means that if your array has null or 0 elements the loop would end, too:

var arr = [1,2,0,4,5];
for(var i=0; arr[i]; i++ ){
  alert( arr[i] );
}

You can avoid this by testing properly:

var arr = [1,2,0,4,5];
for(var i=0; arr[i]!==undefined; i++ ){
  alert( arr[i] );
}

There is also another problem this kind of loop avoids: if you manipulate the array during execution of the loop (for example by removing or moving DOM nodes) you need to change the iterator, too. This example will be an endless loop and lock your browser:

var u = document.getElementsByTagName('ul')[0];
var lis = u.getElementsByTagName(’li’);
for( var i=0; i<lis.length; i++ ){
  u.removeChild(lis[i]);
}

With the other kind of loop that is not a problem. You can for example remove all list items from a UL with:

var u = document.getElementsByTagName('ul')[0];
var lis = u.getElementsByTagName(’li’);
for( var i=0; lis[0]; i++ ){
  u.removeChild( lis[0] );
}



Did I miss something obviously bad about this idea? If so, please tell me, but also consider the other benefits of this for loop to end all for loops:

  • a lot smaller than the YUI, Dojo or Prototype
  • unobtrusive and accessible (if the array is not there nothing happens)
  • may have rounded corners (but they are invisible)
  • cross-browser
  • easy to read
  • heals sick animals when you don’t look

If you wonder about the speed implications of the different styles, check out the speed comparison of for loops test page.

16 Responses to “The only for loop you will ever need *”

  1. Ed Eliot Says:

    An interesting read. I like these back to basics type posts.

  2. Ara Pehlivanian Says:

    This was most helpful, for one thing it’s nice to see someone explain why a reverse loop is faster (I knew it was but not why) and for another, it’s nice to know how to deal with changing sets of data that you’re looping over (i.e. removing node) … I’ve had this problem before but have only been able to deal with it with copies of arrays in the past (iterate over the copy while modifying the original)… great writeup!

  3. david gee Says:

    I’ve been using the (i=0;arr[i];i++) style for a few years now, ever since I saw it posted on the wdf-dom list. never once thought about 0 or null array values could break it, so thanks for that!

  4. Alex Lein Says:

    In your final example, I can think of a better way to remove children from a DOM tree.

    var u = document.getElementsByTagName(’ul’)0;
    while (u.childNodes0) { u.removeChild(u.lastChild) };

    I know it’s not a “for”…
    The lastChild only forces recalculation on .length and .lastChild in the DOM, whereas removing the firstChild of a tree means the DOM needs to recalculate several properties (.firstChild, any CSS rules using :first-child, :first-line, :first-letter, etc) in additional to re-indexing the DOM query.

  5. Chris N. Says:


    var arr = [1,2,0,4,5];
    var i = arr.length; while (i–) {
    alert(arr[i]);
    }

    Your reverse for-loop-fu is strong, but no match for superior reverse while-loop.

  6. mateo Says:


    for(i in arr ){
    alert(arr[i]);
    }

    Regarding this: The for…in syntax isn’t meant to be used for arrays, but for getting the methods and properties of an object. If you use that syntax on an array that has been extended (as is the case when you use prototype) it’ll return the added properties and methods as well.

  7. Victor Welling Says:

    @Ara Pehlivanian:
    If I’m not mistaking, reverse loops are faster, because it’s easier for a computer to check if a value is 0. It doesn’t even have to look at the value: if there’s something there, it ain’t 0, so the comparison fails.

  8. Barry Says:

    @Victor Welling
    Is that actually true? I remember that one of the first lessons I was taught about coding was that null is nothing (i.e. there ain’t anything there), but that 0 is a value (i.e. there is something there)

  9. BarelyBlogging » Blog Archive » links for 2007-04-05 Says:

    [...] Future of the Web How to prevent enter key from submitting the form. (tags: javascript) The only for loop you will ever need * - Wait till I come! Nice way to loop through an array: for(var [...]

  10. Anthony Ettinger Says:

    Fine explanation…I came across the reverse looping in Pro JS Techniques (apress)…and wondered why the John had written it that way.

    Now I know :)

    ps - i’m not exactly sure how to interpret your speed test results.

  11. Looping and Reg Exp helpful links at Advanced CSS Design Resources - last-child.com Says:

    [...] me over the past couple weeks. The first is a new post by Christian Heilmann on looping. The only for loop you will ever need * … * may contain hyperbole to take the mickey out of other [...]

  12. Victor Welling Says:

    @Barry
    Yes, null is nothing (as in, not even a single bit). 0 is a single, yet false (or off) bit. Which, as far as I know, is also rather easy to check for a computer. But, like I said, I might be mistaking ;)

  13. All in a days work… Says:

    [...] the href attribute of the first link - obtrusive, but a start… (tags: JavaScript) The only for loop you will ever need * rounded corners and sick animals - I’m gonna like this fe [...]

  14. Victor Welling Says:

    Ran into a problem today: when using the “array[i] !== undefined” evaluation in Safari to loop through a nodelist (returned by getElementsByTagName), the evaluation never returned false, even at the end of the array. This is due to the fact that nonexistent entries are not “undefined”, but “null” in Safari.

    Rather annoying.

  15. Jake Archibald Says:

    @Victor - Yes, I had to rewrite a script because of this issue too.

    It’s fixed in the latest webkit nightly

  16. Wojtek Says:

    Hey, that was a fun read.

    Going all-out, you might also do:

    for(var i=-1,e; (e=myarray[++i])!==undefined;)
    {
    // variable e already holds the value from your array
    }

    .. since assignment also evaluates to its result.

    At this point however you have to ask yourself if it’s worth the readability. These tests show differences in fairly pretty degenerate cases as they go through a shitload of iterations without doing anything - it’s much more likely the inside of the loop will matter far far more.

    Of course everyone should be discouraged from ever iterating an array with a for-in loop.

Leave a Reply

Wait till I come! is the blog of , a developer evangelist living and working in London, England. Download vcard.

Feed me, Seymour: Entries (RSS) and Comments (RSS).