Jump to content

How to use for Loops in JavaScript

0
  chco's Photo
Posted Oct 10 2010 06:07 PM

The following excerpt from Javascript Patterns explains the different ways to use for loops in Javascript and recommends the best pattern to optimize your code.
In for loops you iterate over arrays or array-like objects such as arguments and HTMLCollection objects. The usual for loop pattern looks like the following:

// sub-optimal loop
for (var i = 0; i < myarray.length; i++) {
    // do something with myarray[i]
}


A problem with this pattern is that the length of the array is accessed on every loop iteration. This can slow down your code, especially when myarray is not an array but an HTMLCollection object.

HTMLCollections are objects returned by DOM methods such as:

  • document.getElementsByName()
  • document.getElementsByClassName()
  • document.getElementsByTagName()


There are also a number of other HTMLCollections, which were introduced before the DOM standard and are still in use today. There include (among others):

document.images
All IMG elements on the page


document.links
All A elements


document.forms
All forms


document.forms[0].elements
All fields in the first form on the page


The trouble with collections is that they are live queries against the underlying document (the HTML page). This means that every time you access any collection’s length, you’re querying the live DOM, and DOM operations are expensive in general.

That’s why a better pattern for for loops is to cache the length of the array (or collection) you’re iterating over, as shown in the following example:

for (var i = 0, max = myarray.length; i < max; i++) {
    // do something with myarray[i]
}


This way you retrieve the value of length only once and use it during the whole loop.

Caching the length when iterating over HTMLCollections is faster across all browsers—anywhere between two times faster (Safari 3) and 190 times (IE7). (For more details, see High Performance Javascript by Nicholas Zakas [O’Reilly].)

Note that when you explicitly intend to modify the collection in the loop (for example, by adding more DOM elements), you’d probably like the length to be updated and not constant.

Following the single var pattern, you can also take the var out of the loop and make the loop like:

function looper() {
    var i = 0,
        max,
        myarray = [];

    // ...

    for (i = 0, max = myarray.length; i < max; i++) {
        // do something with myarray[i]
    }
}


This pattern has the benefit of consistency because you stick to the single var pattern. A drawback is that it makes it a little harder to copy and paste whole loops while refactoring code. For example, if you’re copying the loop from one function to another, you have to make sure you also carry over i and max into the new function (and probably delete them from the original function if they are no longer needed there).

One last tweak to the loop would be to substitute i++ with either one of these expressions:

i = i + 1
i += 1


JSLint prompts you to do it; the reason being that ++ and -- promote “excessive trickiness.” If you disagree with this, you can set the JSLint option plusplus to false. (It’s true by default.) Later in the book, the last pattern is used: i += 1.

Two variations of the for pattern introduce some micro-optimizations because they:

  • Use one less variable (no max)

  • Count down to 0, which is usually faster because it’s more efficient to compare to 0 than to the length of the array or to anything other than 0


The first modified pattern is:

var i, myarray = [];

for (i = myarray.length; i--;) {
    // do something with myarray[i]
}


And the second uses a while loop:

var myarray = [],
    i = myarray.length;

while (i--) {
    // do something with myarray[i]
}


These are micro-optimizations and will only be noticed in performance-critical operations. Additionally, JSLint will complain about the use of i--.

Cover of Javascript Patterns
Learn more about this topic from Javascript Patterns. 

What's the best approach for developing an application with Javascript? This book helps you answer that question with numerous Javascript coding patterns and best practices. If you're an experienced developer looking to solve problems related to objects, functions, inheritance, and other language-specific categories, the abstractions and code templates in this guide are ideal -- whether you're writing a client-side, server-side, or desktop application with Javascript. Author Stoyan Stefanov includes several examples for each pattern as well as practical advice for implementing them.

Learn More Read Now on Safari


Tags:
0 Subscribe


0 Replies