38

I am wondering if JavaScript has an enhanced for loop syntax that allows you to iterate over arrays. For example, in Java, you can simply do the following:

String[] array = "hello there my friend".split(" ");

for (String s : array){
    System.out.println(s);
}

output is:

hello
there
my
friend

Is there a way to do this in JavaScript? Or do I have to use array.length and use standard for loop syntax as below?

var array = "hello there my friend".split(" ");

for (i=0;i<array.length;i++){
    document.write(array[i]);
}

7 Answers 7

46

JavaScript has a foreach-style loop (for (x in a)), but it is extremely bad coding practice to use it on an Array. Basically, the array.length approach is correct. There is also a a.forEach(fn) method in newer JavaScripts you can use, but it is not guaranteed to be present in all browsers - and it's slower than the array.length way.

EDIT 2017: "We'll see how it goes", indeed. In most engines now, .forEach() is now as fast or faster than for(;;), as long as the function is inline, i.e. arr.forEach(function() { ... }) is fast, foo = function() { ... }; arr.forEach(foo) might not be. One might think that the two should be identical, but the first is easier for the compiler to optimise than the second.

Belated EDIT 2020: There is now for (const item of iterable), which solves the downsides of using for (item in iterable).

Sign up to request clarification or add additional context in comments.

9 Comments

Those same newer javascripts actually treat array indices as first-class properties, making it less of a bad practice. (It's still dangerous if you're supporting older js engines of course, or if your Array inherits properties and you don't check for that. Rocket's answer below demonstrates this.)
@Rocket's answer won't protect you from properties set on the object itself. a = [1,2,3]; a.listIndices = function() { for (i in a) { if (a.hasOwnProperty(i)) { console.log(i); } } }; a.listIndices() will list 0; 1; 2; listIndices.
@Amadan: Unset elements won't be iterated over in forEach either.
@Rocket: You are correct. Thankfully, it will skip any nonnumeric indices like listProperty above.
@ziesemer: It's not that simple. If I was going for performance, I would absolutely rather use array.length method (with cached value). jsperf.com/for-vs-foreach/9
|
14

In ES2015(ES6), you can use the for-of loop. It's supported in most browser with the exception of IE.

let array = [10, 20, 30];

for (let value of array) {
  console.log(value);
}

See the Mozilla explanation here

1 Comment

Good concise and complete answer.
13

Using the latest versions of JavaScript available to most modern browsers, you can do this:

array.forEach(function(x){
  document.write(x);
});

Details are at https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/forEach. If you're worried that a browser may not have support for this, you can add it yourself, using a (hopefully minified) version of the implementation that they have listed under "Compatibility".

This is a bit outdated, but this is a minified compatibility version of forEach that I derived from Mozilla's page a few years ago:

if(!Array.prototype.forEach){Array.prototype.forEach=function(b){if(typeof b!="function"){throw new TypeError()}var a=this.length,d=arguments[1],c;for(c=0;c<a;c++){if(c in this){b.call(d,this[c],c,this)}}}};

I've never run into any issues with this, but the implementation on Mozilla's page has since been expanded with some additional checks and code to make it compatible with ECMA-262, Edition 5, 15.4.4.18.

I have a file called common.js that I use and include on all of my pages to include this, as well as all of the other "Array extras" that were introduced with JavaScript 1.6, as listed at https://developer.mozilla.org/en/JavaScript/New_in_JavaScript/1.6#Array_extras. (I've been meaning to get this updated and published for public use.)

This may not be the fastest approach (see http://jsperf.com/for-vs-foreach/15 for some specifics - thanks for the link, Amadan) - but there is something to be said for conciseness and maintainability, etc. Additionally, it'll be very interesting to see how much of this disparity is optimized away by further JavaScript engine improvements over the next few months and years. :-)

Comments

3

You can do for(s in array), but be careful, it's not the same as a foreach.

In this case s is the key (index), not the value. You also need to use hasOwnProperty because in loops though the object's prototype also.

for(s in array){
    if(array.hasOwnProperty(s)){
        console.log(array[s]);
    }
}

EDIT: As @Amadan pointed out, hasOwnProperty does iterate properties when they're added like this: array.test = function(){}. I suggest not using for...in.

EDIT2: If your using a modern web browser (anything that isn't IE < 9), you can use Array.forEach). @ziesemer points out that Mozilla has a shim for this if you need to support IE < 9.

array.forEach(function(s){
    console.log(s);
});

NOTE: Personally I use jQuery for my JavaScript projects, and I use $.each.

$.each(array, function(i,s){
    console.log(s);
});

10 Comments

Why not just use forEach? (See Amadan's or my answer.) Even this approach can break if things are assigned directly to the array that aren't meant to be indexed - even if not through the prototype.
Not all browsers (well I think all but IE) support Array.prototype.forEach.
forEach is supported as of IE 9. For older versions, the compatibility function linked to from my answer can be used to add support for it.
@Rocket you'll get no disagreement here, but I still have to support junk.
@kojiro Array indexes have been first-class properties at least since ES3. I don't have any idea if that was new or not at the time, since that's the earliest version I've really studied. So all browsers support for...in loops on arrays, but it's still not a good idea.
|
2

There's the "forEach" method on the Array prototype in newer JavaScript engines. Some libraries extend the prototype themselves with a similar method.

2 Comments

For example: jQuery has $.each.
@Rocket yes, and Prototype adds ".each" to the Array prototype (or it used to, anyway), and things like Underscore and Functional also do similar things.
2

Try this:

 var errorList = new Array();
 errorList.push("e1");
 errorList.push("e2");
      
 for (var indx in errorList) {
     alert(errorList[indx]);
 }

Comments

1
x = [1,2,3];
for (i in x) {
  console.log(i);
}

1 Comment

This will not work as expected. In a for...in loop, i is the key (index), not the value. You need to console.log(x[i]). You should also check if(x.hasOwnProperty(x)) to make sure you're not iterating over properties in the prototype.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.