Easy loop for every element of an array

There’s something bugging me with javascript for loop : the extra work to loop though all elements of an array. Suppose I want to alert each element of an array, there are three ways of doing it.

First, you loop with an index and assign the element to a variable.

  1. var items = ["a", "b", "c"];
  2. for (var i = 0; i < items.length; i++) {
  3.   var item = items[i];
  4.   alert(item);
  5. }

You always have to have that extra assignment at the beginning of the loop.

Second, you loop with a for each.

  1. var items = ["a", "b", "c"];
  2. for (var i in items) {
  3.   var item = items[i];
  4.   alert(item)
  5. }

In javascript, the for each loops though the index of the array instead of looping though the elements, like in most other languages. Thus, you also have to make the extra assignment at the beginning of the loop.

The easiest way of doing it is the third one.

  1. var items = ["a", "b", "c"];
  2. for (var i = 0, item; item = items[i]; i++) {
  3.   alert(item);
  4. }

How does it work? First it uses multi-assignment on one line. In javascript, you could write var i = 0, j = 1; and it would create two variables, i and j.

The second part of the for is confusing : it assigns the item but it never check if i it is out of bounds of the array (using i < items.length). It works because when javascript tries to assign an item after the end of the array (in our case items[3]), it returns null which is considered by javascript as false.

  • Peter
    The third way of doing it is just standard programming practice. It's how I've always done it in JavaScript, C or any similar language!
  • Asnawi
    If u have a false or null value in the array, u could use typeof like this:

    var items = ["a", "b", false, "c", null];
    for (var i = 0, item; typeof (item = items[i]) != 'undefined'; i++) {
    alert(item);
    }

    but u still have problem if the array contains undefined value, like:

    var items = ["a", undefined, "b"];
  • I wrote about the different types of For loops in JavaScript a while ago. I have also briefly touched on the optimization part of for loops.
  • Stefano
    var items = ["a", "b", "c"];
    for (var i = 0, l = items.length; i < l; alert(items[i++]) );
    // alert can be a lambda
    // pay attention to l = items.length ... don't modify the length of the array inside the loop because it's read once before looping

    "for in" is not so safe...it loops on properties, so the array instance must be "pure array" to work correctly:

    Array.prototype.bar="bar";
    var items = ["a", "b", "c"];
    items.foo='foo';

    for (var p in items) {
    alert(items[p]);
    };
    //shows a, b, c, foo, bar
  • Tobias
    @John

    Perhaps because it says: "Warning: Never use a loop like this on arrays" on https://developer.mozilla.org/En/Core_JavaScrip...

    The 'for (each) in' loops over all the properties of an object. Not just the index of an array.
  • Why not:

    for each (item in items)
    {
    alert(item);
    }

    Is any reasonable environment still stuck with JS < 1.6?
  • Dan
    @Yes, indeed. But you can write something like that : for (var i = 0, item; (item = items[i]) || i < items.length; i++).

    Things are getting out of control! ;)
  • Stick with method #1.

    #2 iterates over the array's properties, which are not necessarily only its values. It should be avoided unless you have a good reason to do it this way.
    #3 fails for the reason Robert pointed out, and also for sparse arrays. For example:

    var items = ["a", "b", "c"];
    items[47] = "d";

    items.length will return 48, so method #1 will find [47] without trouble. Method #3 will stop at [3], because it returns undefined.
  • #3 fails when you have false or null as a value in the array:
    var items = ["a", "b", false, "c"];

    It'll stop before it gets to "c"

    The first solution will correctly iterate over all of them.
  • Dan
    @Rob
    Sorry, my mistake. I edited the post.

    @Femi
    The variable is still manually assigned in the header of the loop, you can't avoid it. In this simple case, it would have been easier to simply write alert(items[i]) but when you have more code than that, it's confusing to always write it completly instead of its shorter version, item.
  • I'm not sure the real benefit here? Enlighten me if wrong.

    You are still manually assigning the variable. Your just doing it on the same line, which as you quite rightly pointed out makes the code fragment more confusing than it appears worth.

    For the above scenario, why not just use style 1 or 2 and alert(items[i])?
  • Rob
    Just tried it, and it looks like a yes. This works fine:

    var items = ["a", "b", "c"];
    for (var i = 0, item; item = items[i]; i++) {
    alert(item);
    }

    Of if you wanted to lump it all together:
    for (var i = 0, item; item = ["a", "b", "c"][i]; i++) {
    alert(item);
    }
  • Rob
    Did you accidentally leave line #3 in the last example?
    I thought the point was to get rid of var item = items[i];
blog comments powered by Disqus