Curently learning Javascript question

Hi all,

Im currently very new to javascript and have a quick question, how do you know what tyoe of loop to use and when?

Kyle

Let’s take the for loop, a for…in loop, a while loop, and a do…while loop as an example.

For loops

A for loop is best to use when you have a known number of iterations that will not change during the loop.

Another useful benefit of the for loop is that you can easily change the increment, allowing you to go forward or backwards, or in this example, to add up the even indexes.

A good for loop:


var values = [1, 3, 4, 6, 7],
    i,
    evenTotal;
for (i = 0; i < values.length; i += 2) {
    evenTotal += values[i];
}
// evenTotal = 1 + 4 + 7 = 12

If however your for loop depends on an array or a collection that will be changing, it’s not such a good idea.

A bad for loop:


var els = document.getElementsByTagName('p'),
    i,
    el;
for (i = 0; i < els.length; i += 1) {
    el = els[i];
    if (el.firstChild.length === 0) {
        el.parentNode.removeChild(el);
    }
}
// Every element removed reduces the size of the els collection
// so the elements immediately following a removed item
// will end up being skipped

The above will have problems whenever a change happens to the collection.

You can avoid that problem by working backwards through the collection.

For…in loops

The for…in loop allows you to iterate over all of the properties of an object.

A good for…in loop:


var dog = {
    name: 'Dug',
    speak: function() {
        alert('Woof!');
    },
    feed: function () {
        alert('Om nom nom');
    },
    find: function (what) {
        if (!what) {
            what = 'food';
        }
        alert('Point at ' + what + '!');
    }
};
for (property in dog) {
    if (typeof dog[property] === 'function') {
        dog[property]();
    }
}
// this dog will do everything he can do: speak, feed, and find

It should not be used for iterating over arrays, because for…in picks up all properties of an object, not just the array indexes themself.

A bad for loop:


Array.prototype.sum = function () {
    var i,
        total = 0;
    for (i in this) {
        total += this[i];
    }
    return total;
};
var values = [1, 2, 4, 7];
alert(values.sum());
// You will not get the expected sum, because along with
// this[0]...this[3] you also get this['sum']

Success is achieved here by using a normal for loop instead of the for…in loop

While loops
A while loop is used so that you do something as long as a condition is still being met.

A good while loop:


var total = 0;
while (total < 10) {
    total += Math.floor(random() * 10);
}
// total will be a whole number from 10 to 19

Be aware that while loops keep on going, even when the results don’t make sense to you.

A bad while loop:


var el = document.getElementById('para');
while (el.nodeName !== 'DIV') {
    el = el.parentNode;
}
// This will error if the paragraph is not contained somewhere inside of a div.

You can fix this by adding a sanity check for the body.


while (el.nodeName !== 'DIV' && el.nodeName !== 'BODY') {
    ...

Do…while loops
A while…do loop is the same as a while loop, except that the condition occurs at the end, not at the start.

This is useful where the condition cannot be checked until afterwards

A do…while loop:


var value,
    total = 0;
do {
    value = Math.floor(random() * 10);
    total += value;
} while (value < 9);
// Will keep adding numbers until a 9 is added

clap clap clap Nice post.

Thanks. While doing it I was thinking that it might be possible for someone to submit is as a course assignment, but even with that small risk, at least others here stand to benefit from it too.

yep, very nice post and examples :tup:

If you would like a summary of it all, I think of it this way

FOR loop - if you know how many iterations there will be

WHILE loop - if the number of iterations is unknown

DO WHILE - if you need to do 1 iteration before testing for some condition.

Firstly great answer pmw57 it clears things up for me quite a bit.

I’m still new to Javascript and in one of the books I’m reading (Object Oriented Javascript p58) the author states that for in loops are designed to iterate objects and arrays.

If possible you give a working example of when for in loops shouldn’t be used on arrays? Just so I can get a better understanding.

Of course.

While it’s technically possible to use for…in on arrays, you should never use it on arrays.

This is because arrays do not consist solely of indexed items. Arrays are objects, just like everything else in javascript, which means that arrays are capable of having other properties on them that you do not expect.

For example: somewhere in your code you have:


for (i in gizmos) {
    ...
}

Then you decide to add someone else’s script to your page, which includes:


Array.prototype.processWidget = function () {

}

All of a sudden your own code stops working.

That is why you should not use for…in for arrays. Because it provides no significant benefit, and it makes your own code fragile.

Your code is much more resilient when you use a standard for loop.

Even the for…in page explicitly says this too:

Although it may be tempting to use this as a way to iterate over an Array, this is a bad idea.

And then goes on to explain why, in detail.

It’s much safer and better to use a standard for loop.


for (i = 0; i < gizmos.length; i += 1) {
    ...
}

There is though in JavaScript 1.6 a forEach method that you can use on arrays instead, which can be more preferable.

However, some web browsers don’t support JavaScript 1.6, or even 1.5 (I’m looking at you, IE), but all is not lost because the forEach page also provides some compatibility code you can use to add that functionality.


if (!Array.prototype.forEach)
{
  Array.prototype.forEach = function(fun /*, thisp */)
  {
    "use strict";

    if (this === void 0 || this === null)
      throw new TypeError();

    var t = Object(this);
    var len = t.length >>> 0;
    if (typeof fun !== "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in t)
        fun.call(thisp, t[i], i, t);
    }
  };
}

Now you can use the forEach method to process your arrays:


gizmos.forEach(function () {
    ...
};

Where the this keyword is for each item in the array

Hey Guys,

Thanks for the excellent examples, having only ever really taken code sourced from the web and dropping it into my code Iv realised I really have got to start knowing what is really going on and how I can customize scripts to best suit my sites needs so here I am trying my best to understand the fundamentals of the language. Im sure you will see more of these types of questions appearing throughout the next few weeks and months, thanks again!

You might find then that our Javascript - Usefull Tips & Tricks will be of some interest.

It’s stickied at the top of the forum too.

Great! thanks pmw!

thanks again for the for-in loop answer makes sense