Three main options:

  1. for (var i = 0; i < xs.length; i++) { console.log(xs[i]); }
  2. xs.forEach((x, i) => console.log(x));
  3. for (const x of xs) { console.log(x); }

Detailed examples are below.


1. Sequential for loop:

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

Pros

  • Works on every environment
  • You can use break and continue flow control statements

Cons

  • Too verbose
  • Imperative
  • Easy to have off-by-one errors (sometimes also called a fence post error)

2. Array.prototype.forEach:

The ES5 specification introduced a lot of beneficial array methods. One of them, the Array.prototype.forEach, gave us a concise way to iterate over an array:

const array = ["one", "two", "three"]
array.forEach(function (item, index) {
  console.log(item, index);
});

Being almost ten years as the time of writing that the ES5 specification was released (Dec. 2009), it has been implemented by nearly all modern engines in the desktop, server, and mobile environments, so it's safe to use them.

And with the ES6 arrow function syntax, it's even more succinct:

array.forEach(item => console.log(item));

Arrow functions are also widely implemented unless you plan to support ancient platforms (e.g., Internet Explorer 11); you are also safe to go.

Pros

  • Very short and succinct.
  • Declarative

Cons

  • Cannot use break / continue

Normally, you can replace the need to break out of imperative loops by filtering the array elements before iterating them, for example:

array.filter(item => item.condition < 10)
     .forEach(item => console.log(item))

Keep in mind if you are iterating an array to build another array from it, you should use map. I've seen this anti-pattern so many times.

Anti-pattern:

const numbers = [1,2,3,4,5], doubled = [];

numbers.forEach((n, i) => { doubled[i] = n * 2 });

Proper use case of map:

const numbers = [1,2,3,4,5];
const doubled = numbers.map(n => n * 2);

console.log(doubled);

Also, if you are trying to reduce the array to a value, for example, you want to sum an array of numbers, you should use the reduce method.

Anti-pattern:

const numbers = [1,2,3,4,5];
const sum = 0;
numbers.forEach(num => { sum += num });

Proper use of reduce:

const numbers = [1,2,3,4,5];
const sum = numbers.reduce((total, n) => total + n, 0);

console.log(sum);

3. ES6 for-of statement:

The ES6 standard introduces the concept of iterable objects and defines a new construct for traversing data, the for...of statement.

This statement works for any kind of iterable object and also for generators (any object that has a \[Symbol.iterator\] property).

Array objects are by definition built-in iterables in ES6, so you can use this statement on them:

let colors = ['red', 'green', 'blue'];
for (const color of colors){
    console.log(color);
}

Pros

  • It can iterate over a large variety of objects.
  • Can use normal flow control statements (break / continue).
  • Useful to iterate serially asynchronous values.

Cons

  • If you are targeting older browsers, the transpiled output might surprise you.

Do not use for...in

@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 be visited in numeric order.
  • Inherited properties are also enumerated.

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

For example:

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

for (var i in array) {
    console.log(array[i]);
}

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

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

The for-in statement, as I said before, is 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...
        console.log("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:

  • Enumeration VS Iteration
Answer from Christian C. Salvadó on Stack Overflow
🌐
Mozilla Hacks
hacks.mozilla.org › home › articles › es6 in depth: iterators and the for-of loop
ES6 In Depth: Iterators and the for-of loop – Mozilla Hacks - the Web developer blog
May 13, 2015 - First, you’re right that for/in uses property names. This is the most efficient way to loop since the Array is built on property names. (Unarguably, a major deficiency in JS, but ES6 doesn’t address it. For-of doesn’t address it. Think WebGL for a case where it REALLY matters.)
🌐
Go Make Things
gomakethings.com › looping-through-arrays-the-es6-way
Looping through arrays the ES6 way | Go Make Things
July 27, 2017 - The traditional way of looping through arrays in vanilla JavaScript is with a for loop: var sandwiches = [ 'tuna', 'ham', 'turkey', 'pb&j' ]; for (var i = 0; i
Discussions

How to iterate through array of objects in ES6
If you return obj.data you will have an array of objects. You need to be more specific about the data you need. ... Sign up to request clarification or add additional context in comments. ... Just use your map function over record.data.userName and not just record.data, you can then print it out using join. Or use a forEach loop ... More on stackoverflow.com
🌐 stackoverflow.com
arrays - Javascript Nested for loop with ES6 - Stack Overflow
I guys, I have a nested for loop but I want to do it with an Array map/ES6 way but how does that work with nested forloops? for (var i = 0; i More on stackoverflow.com
🌐 stackoverflow.com
Which way do you prefer to loop x times in ES6?
for Single iteration No additional objects needed Allows for infinite iterations Iteration count can be changed during iteration Can exit loop during any iteration with break Can be used with await for async iteration Can yield to parent iterator function Cannot be used in an expression context spread operator + forEach Iterates 2 times (spread, forEach) Creates 2 arrays (Array(), [...]) Limited to 4294967295 iterations Iteration count cannot be changed during iteration Cannot break out of loop (except through throw) Iteration is always synchronous (though callbacks can be async) Cannot yield to parent iterator function Exists as an expression resolving to undefined Array.from() Single iteration Creates 1 array plus requires an additional "from" array-like/iterable Limited to 4294967295 iterations Iteration count cannot be changed during iteration Cannot break out of loop (except through throw) Iteration is always synchronous (though mapper can be async) Cannot directly yield to parent iterator function though can participate in yielded values post iteration if delegated with yield* Exists as an expression resolving to array of values defined by mapper Recursion Single iteration No additional objects needed Limits iterations to allowed call stack depth Iteration count can be changed during iteration Can exit loop during any iteration with early return Iteration can be async Cannot directly yield to parent iterator function though can participate in yielded values during iteration if calls delegated with yield* Exists as an expression resolving to first function call return value More on reddit.com
🌐 r/learnjavascript
29
9
August 8, 2023
Access to ES6 array element index inside for-of loop
Instead reverse loop you may cache length jsperf.com/reverse-loop-vs-cache. For-of usefull for iterable processing when you able to process stream without creating big arrays in RAM. Loop speed wouldn't be bottleneck since you will have I/O latency in such cases. More on stackoverflow.com
🌐 stackoverflow.com
Top answer
1 of 16
5293

Three main options:

  1. for (var i = 0; i < xs.length; i++) { console.log(xs[i]); }
  2. xs.forEach((x, i) => console.log(x));
  3. for (const x of xs) { console.log(x); }

Detailed examples are below.


1. Sequential for loop:

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

Pros

  • Works on every environment
  • You can use break and continue flow control statements

Cons

  • Too verbose
  • Imperative
  • Easy to have off-by-one errors (sometimes also called a fence post error)

2. Array.prototype.forEach:

The ES5 specification introduced a lot of beneficial array methods. One of them, the Array.prototype.forEach, gave us a concise way to iterate over an array:

const array = ["one", "two", "three"]
array.forEach(function (item, index) {
  console.log(item, index);
});

Being almost ten years as the time of writing that the ES5 specification was released (Dec. 2009), it has been implemented by nearly all modern engines in the desktop, server, and mobile environments, so it's safe to use them.

And with the ES6 arrow function syntax, it's even more succinct:

array.forEach(item => console.log(item));

Arrow functions are also widely implemented unless you plan to support ancient platforms (e.g., Internet Explorer 11); you are also safe to go.

Pros

  • Very short and succinct.
  • Declarative

Cons

  • Cannot use break / continue

Normally, you can replace the need to break out of imperative loops by filtering the array elements before iterating them, for example:

array.filter(item => item.condition < 10)
     .forEach(item => console.log(item))

Keep in mind if you are iterating an array to build another array from it, you should use map. I've seen this anti-pattern so many times.

Anti-pattern:

const numbers = [1,2,3,4,5], doubled = [];

numbers.forEach((n, i) => { doubled[i] = n * 2 });

Proper use case of map:

const numbers = [1,2,3,4,5];
const doubled = numbers.map(n => n * 2);

console.log(doubled);

Also, if you are trying to reduce the array to a value, for example, you want to sum an array of numbers, you should use the reduce method.

Anti-pattern:

const numbers = [1,2,3,4,5];
const sum = 0;
numbers.forEach(num => { sum += num });

Proper use of reduce:

const numbers = [1,2,3,4,5];
const sum = numbers.reduce((total, n) => total + n, 0);

console.log(sum);

3. ES6 for-of statement:

The ES6 standard introduces the concept of iterable objects and defines a new construct for traversing data, the for...of statement.

This statement works for any kind of iterable object and also for generators (any object that has a \[Symbol.iterator\] property).

Array objects are by definition built-in iterables in ES6, so you can use this statement on them:

let colors = ['red', 'green', 'blue'];
for (const color of colors){
    console.log(color);
}

Pros

  • It can iterate over a large variety of objects.
  • Can use normal flow control statements (break / continue).
  • Useful to iterate serially asynchronous values.

Cons

  • If you are targeting older browsers, the transpiled output might surprise you.

Do not use for...in

@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 be visited in numeric order.
  • Inherited properties are also enumerated.

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

For example:

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

for (var i in array) {
    console.log(array[i]);
}

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

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

The for-in statement, as I said before, is 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...
        console.log("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:

  • Enumeration VS Iteration
2 of 16
1210

Yes, assuming your implementation includes the for...of feature introduced in ECMAScript 2015 (the "Harmony" release)... which is a pretty safe assumption these days.

It works like this:

// REQUIRES ECMASCRIPT 2015+
var s, myStringArray = ["Hello", "World"];
for (s of myStringArray) {
  // ... do something with s ...
}

Or better yet, since ECMAScript 2015 also provides block-scoped variables:

// REQUIRES ECMASCRIPT 2015+
const myStringArray = ["Hello", "World"];
for (const s of myStringArray) {
  // ... do something with s ...
}
// s is no longer defined here

(The variable s is different on each iteration, but can still be declared const inside the loop body as long as it isn't modified there.)

A note on sparse arrays: an array in JavaScript may not actually store as many items as reported by its length; that number is simply one greater than the highest index at which a value is stored. If the array holds fewer elements than indicated by its length, its said to be sparse. For example, it's perfectly legitimate to have an array with items only at indexes 3, 12, and 247; the length of such an array is 248, though it is only actually storing 3 values. If you try to access an item at any other index, the array will appear to have the undefined value there, but the array is nonetheless is distinct from one that actually has undefined values stored. You can see this difference in a number of ways, for example in the way the Node REPL displays arrays:

> a              // array with only one item, at index 12
[ <12 empty items>, 1 ]
> a[0]           // appears to have undefined at index 0
undefined
> a[0]=undefined // but if we put an actual undefined there
undefined
> a              // it now looks like this
[ undefined, <11 empty items>, 1 ]

So when you want to "loop through" an array, you have a question to answer: do you want to loop over the full range indicated by its length and process undefineds for any missing elements, or do you only want to process the elements actually present? There are plenty of applications for both approaches; it just depends on what you're using the array for.

If you iterate over an array with for..of, the body of the loop is executed length times, and the loop control variable is set to undefined for any items not actually present in the array. Depending on the details of your "do something with" code, that behavior may be what you want, but if not, you should use a different approach.

Of course, some developers have no choice but to use a different approach anyway, because for whatever reason they're targeting a version of JavaScript that doesn't yet support for...of.

As long as your JavaScript implementation is compliant with the previous edition of the ECMAScript specification (which rules out, for example, versions of Internet Explorer before 9), then you can use the Array#forEach iterator method instead of a loop. In that case, you pass a function to be called on each item in the array:

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

You can of course use an arrow function if your implementation supports ES6+:

myStringArray.forEach( s => { 
     // ... do something with s ...
} );

Unlike for...of, .forEach only calls the function for elements that are actually present in the array. If passed our hypothetical array with three elements and a length of 248, it will only call the function three times, not 248 times. If this is how you want to handle sparse arrays, .forEach may be the way to go even if your interpreter supports for...of.

The final option, which works in all versions of JavaScript, is an explicit counting loop. You simply count from 0 up to one less than the length and use the counter as an index. The basic loop looks like this:

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

One advantage of this approach is that you can choose how to handle sparse arrays. The above code will run the body of the loop the full length times, with s set to undefined for any missing elements, just like for..of; if you instead want to handle only the actually-present elements of a sparse array, like .forEach, you can add a simple in test on the index:

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

Depending on your implementation's optimizations, 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 since it skips a property lookup each time through. You may see the length caching done in the loop initialization clause, like this:

var i, len, myStringArray = [ "Hello", "World" ];
for (len = myStringArray.length, i=0; i<len; ++i) {

The explicit counting loop also means you have access to the index of each value, should you want it. The index is also passed as an extra parameter to the function you pass to forEach, so you can access it that way as well:

myStringArray.forEach( (s,i) => {
   // ... do something with s and i ...
});

for...of doesn't give you the index associated with each object, but as long as the object you're iterating over is actually an instance of Array (and not one of the other iterable types for..of works on), you can use the Array#entries method to change it to an array of [index, item] pairs, and then iterate over that:

for (const [i, s] of myStringArray.entries()) {
  // ... do something with s and i ...
}

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 an automatically-updated 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 (remember that even methods are actually just properties whose value is a closure), nor is it guaranteed to iterate over those in numeric order. Therefore, the for...in syntax should not be used for looping through Arrays.

🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Statements › for...of
for...of - JavaScript | MDN - MDN Web Docs
The for...of loop iterates and logs values that iterable, as an array (which is iterable), defines to be iterated over.
🌐
DEV Community
dev.to › godcrampy › es6-for-loops-best-practices-4c86
ES6 for loops: Best Practices - DEV Community
August 25, 2019 - The ES6 revision also provides two new for loops the for..of and for..in loop. ... let primes = [2, 3, 5, 7]; for(const value of primes) { console.log(value); } // 2 // 3 // 5 // 7 // Iterates over the values of the array
🌐
Medium
alexandermgabriel.medium.com › es6-for-of-and-in-loops-f73cdad1c206
ES6 For Of and In Loops. During my time at my coding bootcamp, I… | by Alexander Gabriel | Medium
May 23, 2021 - Basically, you are declaring the variable and then state the array you are iterating over. And that’s it! Now, I also found out you can iterate over an object as well. With a For- In loop: const object = { a: 1, b: 2, c: 3 };for (const property ...
🌐
Exploring JS
exploringjs.com › es6 › ch_for-of.html
17. The for-of loop
for-of is a new loop in ES6 that replaces both for-in and forEach() and supports the new iteration protocol. Use it to loop over iterable objects (Arrays, strings, Maps, Sets, etc.; see Chap.
Find elsewhere
🌐
John Kavanagh
johnkavanagh.co.uk › home › articles › looping in modern javascript: foreach and for...of
Looping in JavaScript ES5 and ES6 : forEach and for...of
December 13, 2024 - With this code, we're setting up our iteration to start on 0, and loop as long as i is less than the length of our array (a).
🌐
Codez Up
codezup.com › home › ways to loop through javascript arrays | es6
Ways to Loop through Javascript Arrays | ES6 | Codez Up
July 27, 2022 - This forEach() method loops the array in order and passes the index as the 2nd argument to the function. So, these are the ways through which you can loop on javascript arrays in ES6.
🌐
freeCodeCamp
freecodecamp.org › news › how-to-loop-through-an-array-in-javascript-js-iterate-tutorial
How to Loop Through an Array in JavaScript – JS Iterate Tutorial
November 7, 2024 - When i = 6, the condition will no longer be executed because the array's last index is 5. The do...while loop is nearly identical to the while loop, except that it executes the body first before evaluating the condition for subsequent executions.
🌐
JavaScript in Plain English
javascript.plainenglish.io › demystifying-the-es6-for-of-loop-9c1a0166d1c6
Demystifying the ES6 ‘for-of’ Loop | by Let Me Code! | JavaScript in Plain English
April 25, 2023 - This has been around since the first ES6 edition and allows the programmer to loop through the enumerable properties of a JavaScript ‘iterable.’ · This means that when used for an array, the variable in the for-in loop will return the index, and for an object it will return the key.
🌐
Reddit
reddit.com › r/learnjavascript › which way do you prefer to loop x times in es6?
r/learnjavascript on Reddit: Which way do you prefer to loop x times in ES6?
August 8, 2023 -

This question came to my mind when I had to render some random content a certain number of times and came up with four solutions. So I was wondering if I should choose one over the others, maybe for performance reasons.

Below are my approaches. Note that no index is needed, I just determine how many times to loop.

Using for:

for (let i = 0; i < 6; i++) {
  console.log("Repeat")
}

Using the spread operator:

[...Array(6)].forEach(() => {
  console.log("Repeat");
});

Using Array.from():

Array.from({ length: 6 }, () => {
  console.log("Repeat");
});

Using Recursion:

function repeat(num) {
  if (num === 0) return;
  console.log("Repeat")
  repeat(num - 1)
}

repeat(6);

So, are there any significant differences? If so, what are they? Or maybe some of you would take a completely different approach?

Thanks in advance.

Top answer
1 of 13
73
for Single iteration No additional objects needed Allows for infinite iterations Iteration count can be changed during iteration Can exit loop during any iteration with break Can be used with await for async iteration Can yield to parent iterator function Cannot be used in an expression context spread operator + forEach Iterates 2 times (spread, forEach) Creates 2 arrays (Array(), [...]) Limited to 4294967295 iterations Iteration count cannot be changed during iteration Cannot break out of loop (except through throw) Iteration is always synchronous (though callbacks can be async) Cannot yield to parent iterator function Exists as an expression resolving to undefined Array.from() Single iteration Creates 1 array plus requires an additional "from" array-like/iterable Limited to 4294967295 iterations Iteration count cannot be changed during iteration Cannot break out of loop (except through throw) Iteration is always synchronous (though mapper can be async) Cannot directly yield to parent iterator function though can participate in yielded values post iteration if delegated with yield* Exists as an expression resolving to array of values defined by mapper Recursion Single iteration No additional objects needed Limits iterations to allowed call stack depth Iteration count can be changed during iteration Can exit loop during any iteration with early return Iteration can be async Cannot directly yield to parent iterator function though can participate in yielded values during iteration if calls delegated with yield* Exists as an expression resolving to first function call return value
2 of 13
23
console.log("Repeat"); console.log("Repeat"); console.log("Repeat"); console.log("Repeat"); console.log("Repeat"); console.log("Repeat");
🌐
GeeksforGeeks
geeksforgeeks.org › es6-loops
ES6 Loops | GeeksforGeeks
April 27, 2023 - for...of The for...of the loop is used to execute the loop block to iterate the iterable instead of object literals. ... In each iteration, one property from the iterable(array, string, etc) is assigned to the variable_name and this loop continues ...
🌐
TutorialsPoint
tutorialspoint.com › es6 › es6_array_method_foreach.htm
ES6 - Array Method forEach()
var nums = new Array(12,13,14,15) console.log("Printing original array......") nums.forEach(function(val,index) { console.log(val) }) nums.reverse() //reverses the array element console.log("Printing Reversed array....") nums.forEach(function(val,index){ console.log(val) })
🌐
CoreUI
coreui.io › blog › how-to-loop-through-an-array-in-javascript
How to loop through an array in JavaScript · CoreUI
July 23, 2024 - It’s a straightforward way to ... i++) { console.log(numbers[i]) } Introduced in ES6, the for…of loop iterates directly over array elements....