In Java you can use a for() loop to go through objects in an array like so:

String[] myStringArray = {"Hello","World"};
for(String s : myStringArray)
{
    //Do something
}

can you do the same in JavaScript?

share|improve this question

1  
Ok, so I'm a bit confused, it's ok to use the enhanced for loop when you are accessing the objects? And use a sequential one for filling one? Is this correct? – Mark Szymanski Jun 10 '10 at 0:15
3  
no, it's really simple, array objects have numeric indexes, so you want to iterate over those indexes in the numeric order, a sequential loop ensures that, the enhanced for-in loop enumerates object properties, without an specific order, and it also enumerates inherited properties... for iterating over arrays sequential loops are always recommended... – CMS Jun 10 '10 at 0:38
related - stackoverflow.com/questions/5349425/… – jondavidjohn Nov 1 '11 at 17:53
1  
Any chance you could consider switching your accepted answer for this question? The community thinks that CMS' answer is superior to the one that solved your problem. Thanks. – Gray Apr 10 at 13:18
1  
This question and answers are in woeful need of cleanup & clarification. – Tchalvak Apr 12 at 12:49
feedback

11 Answers

Use a sequential for loop:

var myStringArray = ["Hello","World"];
for (var i = 0; i < myStringArray.length; i++) {
    alert(myStringArray[i]);
    //Do something
}

@zipcodeman suggests the use of the for...in statement, but for iterating arrays for-in should be avoided, that statement is meant to enumerate object properties.

It shouldn't be used for array-like objects because:

  • The order of iteration is not guaranteed, the array indexes may not visited in the numeric order.
  • Inherited properties are also enumerated.

The second point is can give you a lot of problems, for example, if you extend the Array.prototype object to include a method there, that property will be also enumerated.

For example:

Array.prototype.foo = "foo!";
var array = ['a', 'b', 'c'];

for (var i in array) {
  alert(array[i]);
}

The above code will alert, "a", "b", "c" and "foo!".

That be particularly a problem if you use some library that relies heavily on native prototypes augmention (such as MooTools for example).

The for-in statement as I said before it's there to enumerate object properties, for example:

var obj = {
  "a": 1,
  "b": 2,
  "c": 3
};

for (var prop in obj) {
  if (obj.hasOwnProperty(prop)) { 
  // or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety...
    alert("prop: " + prop + " value: " + obj[prop])
  }
}

In the above example the hasOwnProperty method allows you to enumerate only own properties, that's it, only the properties that the object physically has, no inherited properties.

I would recommend you to read the following article:

share|improve this answer
11  
Why the down-vote? for...in should be avoided for Array-like objects! – CMS Jun 10 '10 at 0:10
4  
This is the reason ( by CMS him self ) stackoverflow.com/questions/1885317/… – OscarRyz Jun 10 '10 at 0:13
3  
+1 for adding explanation why not to use for( in ) – OscarRyz Jun 10 '10 at 0:24
8  
please cache the length of the array in your answer – Gabriel May 16 '11 at 22:52
2  
@DoubleGras, I think that is an opinion that is not shared by everyone. See: stackoverflow.com/questions/5752906/… or groups.google.com/forum/?fromgroups#!topic/jsmentors/… – Matthijs Wessels Aug 14 at 16:41
show 6 more comments
feedback

You can use map (also known as apply in other languages like python, and probably haskell too)

[1,2,3,4].map( function(item) {
     alert(item);
})

The general syntax is:

array.map(func)

func should take one parameter.

The return value of array.map is another array, so you can use it like this:

var x = [1,2,3,4].map( function(item) { return item * 10; } );

And now x is [10,20,30,40]

EDIT:

I must clarify: this concept is from the functional paradigm.

You don't have to write the function inline; one might do so as a first sketch, but you could then extract it into its own function.

var item_processor = function(item) {
      // do something complicated to an item 
}

new_list = my_list.map(item_processor);

which would be sort-of equivalent to:

 for(item in my_list) { item_porcessor(item); }

except you don't get the new_list.

share|improve this answer
3  
No, but it can be more powerful. check this out: joelonsoftware.com/items/2006/08/01.html – hasen j Jun 10 '10 at 0:14
7  
That particular example is probably better implemented using Array.forEach. map is for generating a new array. – harto Jun 10 '10 at 0:20
5  
@hasen, the Array.prototype.map method is part of the ECMAScript 5th Edition Standard, is not yet available on all implementations (e.g. IE lacks of it), also for iterating over an array I think the Array.prototype.forEach method is more semantically correct... also please don't suggest the for-in statement, see my answer for more details :) – CMS Jun 10 '10 at 0:30
2  
aagh .. remind me again why I hate IE? – hasen j Jun 10 '10 at 0:31
1  
If you check out the link CMS provided, there's an implementation you can use in browsers that don't natively support it. – harto Jun 10 '10 at 4:42
show 8 more comments
feedback

In JavaScript it's not advisable to loop through an Array with a for-in loop, but it's better using a for loop such as:

for(var i=0, len=myArray.length; i < len; i++){}

It's optimized as well ("caching" the array length). If you'd like to learn more, read my post on the subject.

share|improve this answer
2  
Straight forward, thanks. – Horst Walter Aug 19 '11 at 11:10
myArray.forEach(function(obj) {}); is still the best – Jannis Jan 2 at 19:47
a tiny improvement: you could use ++i instead of i++ – roberkules Apr 12 at 14:58
++i is an old school optimization that modern compilers do for you in a for loop since a long time ago :) stackoverflow.com/a/1547433/1033348 – ngryman Apr 15 at 0:45
@Jannis .forEach has several things against it. 1) not native 2) Requires a new execution context for EVERY index which is rather expensive and seems like overkill (see dmitrysoshnikov.com/ecmascript/chapter-1-execution-contexts) – Jose May 8 at 13:03
feedback

To directly answer the question: no, you can't. JavaScript does not have a concise syntax for iterating over Arrays. At least, not universally.

If you want code that is both efficient and universal (that is, it runs in all browsers and other js interpreters), you need to use an explicit counting loop. The safest version, which handles sparse arrays properly, is this:

var myStringArray = [ "Hello", "World" ]
var len = myStringArray.length
for (var i=0; i<len; ++i) {
  if (i in myStringArray) {
    var s = myStringArray[i];
    ... do something with s ...
  }
}

Assigning the length value to the local variable (as opposed to including the full myStringArray.length expression in the loop condition) can make a significant difference in performance; using Rhino on my machine, the speedup is 43%.

If you're willing to restrict yourself to a subset of available JavaScript engines, then you can use the enhanced looping method forEach, which takes a function that is called once per item in the array, and automatically handles sparse arrays properly:

var myStringArray = [ "Hello", "World" ]
myStringArray.forEach( function(s) { 
     ... do something with s ...
} )

The performance of forEach actually beats the explicit counting loop with a local length var by a factor of 2 in SpiderMonkey (again, on my machine). It's slower in Rhino, but only barely, while still being faster than the counting loop without the cache var.

The for...in syntax mentioned by others is for looping over an object's properties; since an Array in JavaScript is just an object with numeric property names (and a magical "length" property), you can theoretically loop over an Array with it. But the problem is that it doesn't restrict itself to the numeric property values, and in JavaScript, even methods are actually just properties whose value is a closure. Therefore, the for...in syntax should not be used for looping through Arrays. (It's not so great for generic Objects being used as maps/hashes/dictionaries, either, to be honest.)

share|improve this answer
Note that some interpreters (e.g. V8) will automatically cache the length of the array if the code is called enough times and it detects that the length is not modified by the loop. While caching the length is still nice, it may not provide a speed boost when your code is being invoked enough times to actually make a difference. – Phrogz Jun 4 at 16:29
feedback

Opera, Safari, Firefox and Chrome now all share a set of enhanced Array methods for optimizing many common loops.

You may not need all of them, but they can be very useful, or would be if every browser supported them.

The mozilla labs published the algorithms they and webkit both use, so that you can add them yourself.

filter returns an array of items that satisfy some condition or test.

every returns true if every array member passes the test.

some returns true if any pass the test.

forEach runs a function on each array member and doesn't return anything.

map is like forEach, but it returns an array of the results of the operation for each element.

These methods all take a function for their first argument, and have an optional second argument, which is an object whose scope you want to impose on the array members as they loop through the function.

Ignore it until you need it.

indexOf and lastIndexOf find the appropriate position of the first or last element that matches its argument exactly.

(function(){
    var p, ap= Array.prototype, p2={
        filter: function(fun, scope){
            var L= this.length, A= [], i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        val= this[i];
                        if(fun.call(scope, val, i, this)){
                            A[A.length]= val;
                        }
                    }
                    ++i;
                }
            }
            return A;
        },
        every: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && !fun.call(scope, this[i], i, this)) return false;
                    ++i;
                }
                return true;
            }
            return null;
        },
        forEach: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
            }
            return this;
        },
        indexOf: function(what, i){
            i= i || 0;
            var L= this.length;
            while(i< L){
                if(this[i]=== what) return i;
                ++i;
            }
            return -1;
        },
        lastIndexOf: function(what, i){
            var L= this.length;
            i= i || L-1;
            if(isNaN(i) || i>= L) i= L-1;
            else if(i< 0) i += L;
            while(i> -1){
                if(this[i]=== what) return i;
                --i;
            }
            return -1;
        },
        map: function(fun, scope){
            var L= this.length, A= Array(this.length), i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        A[i]= fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
                return A;
            }
        },
        some: function(fun, scope){
            var i= 0, L= this.length;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && fun.call(scope, this[i], i, this)) return true;
                    ++i;
                }
                return false;
            }
        }
    }
    for(p in p2){
        if(!ap[p]) ap[p]= p2[p];
    }
    return true;
})();
share|improve this answer
Useful, Thanks! – Timo Huovinen Mar 21 at 11:09
feedback

Can't beleive no one mentioned using the while loop...

var i=0,item,items = ['one','two','three'];
while(item=items[i++]){
    console.log(item);
}

logs: 'one','two','three'

and for the reverse order, an even more efficient loop

var items = ['one','two','three'], i=items.length;
while(i--){
    console.log(items[i]);
}

logs: 'three','two','one'

or the classical for loop

var items = ['one','two','three']
for(var i=0,l=items.length; i < l ; i++){
    console.log(items[i]);
}

logs: 'one','two','three'

reference: http://www.sitepoint.com/google-closure-how-not-to-write-javascript/

share|improve this answer
2  
The first example of the "while" syntax won't work if any of the array elements is falsy. – QmunkE Apr 16 at 14:42
@QmunkE yep, thanks for mentioning that. – Timo Huovinen Apr 16 at 14:45
feedback

ok, seriously do not use the method that includes looking up the length on each iteration.

var i = 0,
    item;
for ( ; item = myStringArray[i++] ; ){
  item; // this is the string at the index
}

or if you really want to get the id and have a really classical for loop:

var i = 0,
    len = myStringArray.length;

for ( ; i < len ; i++ ){
  myStringArray[i]; // don't use this if you plan on changing the length of the array
}
share|improve this answer
1  
Note that some interpreters (e.g. V8) will automatically cache the length of the array if the code is called enough times and it detects that the length is not modified by the loop. – Phrogz Jun 4 at 16:28
Thanks for the info @Phrogz it's true that there is a lot of optimizations that the VM can make, but since older browsers don't have this it would still be best practice to optimize for it since it is so cheap. – Gabriel Jun 26 at 1:43
feedback

I would thoroughly recommend making use of the underscore.js library. It provides you with various functions that you can use to iterate over arrays/collections.

For instance:

_.each([1, 2, 3], function(num){ alert(num); });
=> alerts each number in turn...
share|improve this answer
feedback

There's a method to iterate over only own object properties, not including prototype's ones:

for (var i in array) if (array.hasOwnProperty(i)) {
    // do something with array[i]
}

but it still will iterate over custom-defined properties.

In javascript any custom property could be assigned to any object including array.

If one wants to iterate over sparsed array, for (var i = 0; i < array.length; i++) if (i in array) or array.forEach with es5shim should be used.

share|improve this answer
feedback

It's not 100% identical, but similar:

var myStringArray = ['Hello', 'World']; // array uses [] not {}
for (var i in myStringArray) {
    console.log(i + ' -> ' + myStringArray[i]); // i is the index/key, not the item
}
share|improve this answer
It seems that this would run up against similar problems as other for in usages with an array object, in that prototype member variables would be caught by the for in as well. – Tchalvak Apr 18 at 15:34
feedback

If you want a terse way to write a fast loop and you can iterate in reverse:

for (var i=myArray.length;i--;){
  var item=myArray[i];
}

This has the benefit of caching the length (similar to for (var i=0,len=myArray.length;i<len;++i) and unlike for (var i=0;i<myArray.length;++i)) while being fewer characters to type.

There are even some times when you ought to iterate in reverse, such as when iterating over a live NodeList where you plan on removing items from the DOM during iteration.

share|improve this answer
feedback

Your Answer

 
or
required, but never shown
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.