WEBSITE

JavaScript Patterns : Essentials - for Loops

8/28/2012 8:34:40 PM
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.) 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--.

Other  
 
Top 10
Review : Sigma 24mm f/1.4 DG HSM Art
Review : Canon EF11-24mm f/4L USM
Review : Creative Sound Blaster Roar 2
Review : Philips Fidelio M2L
Review : Alienware 17 - Dell's Alienware laptops
Review Smartwatch : Wellograph
Review : Xiaomi Redmi 2
Extending LINQ to Objects : Writing a Single Element Operator (part 2) - Building the RandomElement Operator
Extending LINQ to Objects : Writing a Single Element Operator (part 1) - Building Our Own Last Operator
3 Tips for Maintaining Your Cell Phone Battery (part 2) - Discharge Smart, Use Smart
REVIEW
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
VIDEO TUTORIAL
- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
Popular Tags
Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8
Visit movie_stars's profile on Pinterest.