For loops, while loops, fruit loops…

There are a lot of different kinds of ways to write loops in Javascript. You have your standard for loop and while loop, but beyond that you have the do-while loop, the object properties loop, and lots of different variation of all four “basic” loops. In this post, we’ll examine the four basic loops, the reverse for loop, the reverse while loop, the short reverse while loop, object property loops, and more. I’ll also explain a bit about loop unrolling and where/how it can help you optimize your code. Read on, if you dare!

The classic for loop

What I like to call the classic for loop is perhaps the most basic of all loops in Javascript. It looks like this:

for(var i = 0; i<10; i++) { 
    // do stuff with i 
}

This is the basic loop model provided by Javascript and is by far the most common variation of the for loop. You initialize an iterator (i), set a finish condition for i, and finally specify how i will be modified each iteration of the loop. Since i++ is just a statement, it’s possible to modify i however you want in the loop header using statement operators. for(var i = 0; i<10; i+= 2) will increment i by two each iteration, for example.

Note: You have to be careful. If you initialize the loop without putting var in front of the iterator variable (like this: for(i = 0; i<10; i++)), you’ll turn it into a global variable, which may not be what you were intending to do.

Using the for loop to iterate through an array

Assuming you have an array called things, you can use a for loop to iterate through it like so:

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

The classic while loop

The while loop is another basic, very familiar loop. It’s a little more complicated than the for loop, but not by much. You can’t write it all on one line, but it’s about as simple as they come:

var i = 0; 

while(i < 10) { 
    // do stuff with i
  
    i++; 
}

As you can see, you have to initialize i outside the loop and then increment it inside the loop. That’s why this method isn’t quite as clean as the basic for loop. However, I think it’s a bit easier to understand, because it’s more broken up. Because of this broken up format, it’s possible to do a lot with while loops, as you’ll see shortly.

Note: You’ll want to make sure you do all your loop operations before you increment your iterator variable; otherwise, you risk skipping an iteration of your loop.

The quick n’ dirty while loop

This method is one of the shortest methods of writing a loop, and it’s probably one of fastest, too.

var i = 10; 
while(i--) { 
    // do stuff with i, which is in the range 9 to 0 
}

The reason this works and isn’t an infinite loop is that the while loop performs each iteration only when its condition evaluates to a truthy value (that is, anything that can’t be coerced into 0, or false). Since 0 is a falsy value, the condition evaluates to false and the loop performs its last iteration before exiting. Pretty neat, huh?

Using the while loop to iterate through an array

There are a few different ways to iterate through an array with a while loop, but they’re just slight variations of the previous while loops. Here’s the basic forward-iterating while loop:

// forward declaring our variables because that's recommended.
var len = things.length, 
          currentThing, 
          i;

while(i < len) {
    // do stuff with the current thing
    currentThing = things[i]; 
    
    // increment our counter 
    i++; 
}

As you can see, I cached the length of the array to speed up performance a micro-bit. Don’t do this if you’re modifying the length of your array inside the while loop. Instead, compare i to the length of the array every iteration.

And here’s the reverse while loop:

var i = things.length, 
        currentThing;

while(i--) {
    // do stuff with the current thing 
    currentThing = things[i]; 
}

This is the preferred way to loop through an array if you’re going to use a while loop. Since it’s reversed, it doesn’t care if you’re modifying the length of the array or chucking elements in each iteration (as long as you aren’t modifying elements ahead of the loop, of course). You also don’t have to define as many variables, since we no longer need to cache the length of the array.

The do-while loop

The do-while loop is similar to the while loop in many ways, barring syntax. It’s a broken up loop in which you have to manually increment your variable. However, the key difference here is that the do-while loop executes the statement and then evaluates the provided condition, meaning the loop will execute at least once. Here’s what it looks like:

var i = 0;
do {
    // do stuff with i, which is in the range 0-9
    
    // remember, increment your counter at the very end of the loop 
    i++; 
} while (i < 10);

As you can see, not too different from the while loop, except for a little change in the syntax. The main difference is, even if the condition at the bottom evaluates to false, the loop will still run once:

var i = 0;

do { 
    i++; 
} while (i < -1); // still evaluates once

I haven’t really found a use for the do-while loop yet, so if you do, feel free to let me know what you did with it in the comments below. 😛

The Array.forEach loop

Array.forEach is a relatively new addition to the ECMA-262 standard, so it’s not seen a lot of use yet, nor do many older browsers support it. Nonetheless, there is a shim for it and it’s a remarkably useful function. Here’s some example usage:

var a = ["a", "b", "c", "d", "e"];

a.forEach(function(element, index, array) {
    console.log("Element: " + element + " at index " + index); 
});

As you can see, the syntax is quite simple. Simply call forEach on an array and pass in the function you want executed on each of the array’s elements. As I mentioned before, for browsers that don’t natively support forEach, there’s a shim (which can be found in Mozilla’s forEach documentation):

if ( !Array.prototype.forEach ) { 
    Array.prototype.forEach = function(fn, scope) { 
        for(var i = 0, len = this.length; i < len; ++i) {
            fn.call(scope, this[i], i, this); 
        } 
    } 
}

Simply include the above code in your Javascript project and you’ll have full support for the forEach function. Although it really just serves as syntactic sugar to cover the for loop, you have to admit it is quite nice to have.

Object property loops

The object property loop is a way of looping over the properties of objects that aren’t arrays, since you can’t really use the normal for loop or while loop to loop through the elements of an object effectively. Here’s how it works:

var currentProp;

for(prop in obj) { 
    if(obj.hasOwnProperty(prop)) { 
        currentProp = obj[prop]; // do something with this property, where currentProp is the actual value 
                                 // you're looking at, and prop is the name of that value on the object. 
    } 
}

One of the things you need to make sure you do is check to make sure the property of the object you’re looping over actually belongs to that object and hasn’t come down the prototype chain. If you don’t do that, properties such as functions from the object’s prototype will become part of the loop. Not cool.

Another thing to be aware of is that the object won’t be looped over necessarily in the order that the properties are specified, nor even in the same order each time the properties are looped through. A plain object is not like an array in this respect, so you’ve got to be careful how you handle it.

Partial loop unrolling (and when not to use it)

Partial loop unrolling is a nice trick to have up your sleeve, especially if you’re working with large arrays (arrays with entries in the thousands or more). Basically, loop unrolling just means covering more than one element in each iteration of your loop. Here’s an example:

var currentThing;

for(var i = 0, len = things.length; i<len; i+=4) { 
    currentThing = things[i]; // do something with the current thing
    currentThing = things[i+1]; // do something with the next thing
    currentThing = things[i+2]; // do something with the next next thing
    currentThing = things[i+3]; // do something with the last next thing 
}

Since you’re effectively cutting your amount of iterations by half, or two thirds, or three quarters, or four fifths, or whatever amount you choose, it’s easy to see why this method should speed up your performance. However, interestingly enough, the gain you get by partially unrolling your loop isn’t that great. Therefore this isn’t a very effective method for speeding up your code until you’ve got arrays with elements numbering in the thousands (or higher).

Wrapping up

Well, that just about covers it for the most commonly used loops. I hope this helps, and, as always, If I’ve made any mistakes or typos, or if you just want to suggest something, feel free to leave me a note in the comments! Thanks for reading.

Oh, and as for fruit loops… do I really have to explain those? :-)

5 thoughts on “For loops, while loops, fruit loops…”

  1. Thanks! Very simple topic but I have to admit that I didn’t know obj.hasOwnProperty and Array.forEach.This (trivial) snippet does the same for object properties:

    Object.prototype.forEach = function(fn) {for (var property in this) {if (this.hasOwnProperty(property)) {fn(this[property], property, this);}}};

    It isn’t complete as in MDN Array.forEach but it might help someone.

  2. Hey, that’s a neat snippet. And although an array is an object, the array prototype overrides the object prototype, since it’s lower down on the prototype chain, so Array.forEach is still used on arrays, but Object.forEach is used on everything else. I can see this coming in handy–thanks for sharing!

  3. Iterating over an objects own properties happens in ES5 much nicer than a for (prop in obj) loop with an hasOwnProperty like so:

    Object.keys(obj).forEach(function iterator(prop) &#123;<br />        console.log(prop + ': ' + obj[prop]);<br />    &#125;);
    1. Well it seems your blog adds some weird html to the code. Remove the br-tags if you’re going to use the code.

Leave a Reply

Your email address will not be published. Required fields are marked *