of in JavaScript: walking through values with a for...of loop

The of keyword forms the for...of loop, which walks the values of an array, a string, a Map or a Set. How it differs from for...in and from forEach.
3 min read
Believemy logo

Walking an array once required a counter, a condition and an increment, which is three chances to make a mistake on a trivial operation. The for...of loop removed that ceremony: it hands you the values directly, one at a time.

The word of is used almost nowhere else in the language. It separates the variable receiving each value from the collection being walked.


Definition

of is the keyword of the for...of loop, which walks the values of an iterable collection and runs its block once per value.

JAVASCRIPT
const items = ['tea', 'coffee', 'sugar'];

for (const item of items) {
  console.log(item);
}
// 'tea', then 'coffee', then 'sugar'

The variable is declared with const in the vast majority of cases: it is recreated on every pass, and nothing inside the block needs to change it.


for...of or for...in

The two loops differ by one word and do entirely different things. This is the most common confusion in the language on this subject.

LoopWhat it gives youOn an array
for...ofThe values'tea', 'coffee'
for...inThe property names'0', '1', as text

On an array, for...in returns indexes as strings, and throws inherited properties into the mix as well. Keep the simple rule: of for the values of a collection, in for the keys of an object.


What can be walked, and what cannot

The loop accepts anything the language considers iterable: an Array, a string, a Map, a Set, the results of a selection in a page.

JAVASCRIPT
for (const letter of 'tea') { }            // 't', 'e', 'a'
for (const value of new Set([1, 1, 2])) { } // 1, 2
for (const [key, value] of new Map()) { }   // pairs

A plain object, on the other hand, is not iterable: the loop raises an error. The way through is Object.entries(), paired with Destructuring to pick up the key and the value.

JAVASCRIPT
const stock = { tea: 12, coffee: 3 };

for (const [product, quantity] of Object.entries(stock)) {
  console.log(product, quantity);
}


What forEach cannot do

The Array.forEach() method is shorter, but it cannot be interrupted. A break or a continue has no effect inside it, and an await within is never waited for.

JAVASCRIPT
for (const id of ids) {
  const record = await load(id);
  if (!record) break;
}
Good to know

That is the most reliable way to choose: as soon as you need to stop partway or wait for something on each pass, for...of is the answer. For a simple transformation, Map or Array.filter() stay more expressive.


Frequently asked questions

Question

How do I get the index along with the value?

An array's entries() method returns pairs, which unpack straight into the loop: for (const [i, value] of items.entries()). It reads better than keeping a separate counter, and the index always stays in step with the value.


Question

Why does my object raise an error?

Because a plain object does not know how to be walked: the message says it is not iterable. Go through Object.keys(), Object.values() or Object.entries() depending on what you need, since all three return arrays.


Question

Does the word of appear anywhere else in the language?

You meet it again in for await...of, used to walk values that arrive over time, and in the Array.of() method, which builds an array from the values it receives. Note that Array.of(7) gives a one-element array, where Array(7) creates one with seven empty slots.

Related terms

Discover our javaScript glossary

Every word of JavaScript explained simply: keywords, built-in objects, methods, errors and concepts. Clear definitions and examples that actually run, to learn and to troubleshoot.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.