Skip to main content

How to Iterate Over the Elements of a Set in JavaScript

A Set in JavaScript is a collection of unique values that preserves insertion order. A fundamental task when working with a Set is to iterate over its elements to read, process, or display them. Modern JavaScript provides two primary, idiomatic ways to do this: the for...of loop and the forEach() method.

This guide will demonstrate both of these methods, explain their key differences, and provide a clear recommendation on which one to use for different scenarios.

The for...of loop is the modern, standard, and most flexible way to iterate over any iterable object in JavaScript, including Set objects. Its syntax is clean, readable, and it supports control flow statements like break and continue.

For example, you have a Set and you want to process each of its elements.

// Problem: Log each item in the set to the console.
const mySet = new Set(['apple', 'banana', 'cherry']);

Solution:

let mySet = new Set(['apple', 'banana', 'cherry']);

for (let item of mySet) {
console.log(item);
}

Output:

apple
banana
cherry
note

This is the recommended best practice for most iteration needs.

An Alternative Method: Set.prototype.forEach()

Like arrays, Set objects also have a forEach() method. This is a good choice for a functional programming style, especially when you don't need to break out of the loop early.

let mySet = new Set(['apple', 'banana', 'cherry']);

mySet.forEach(item => {
console.log(item);
});

Output:

apple
banana
cherry

The callback function you provide to forEach() is called once for each element in the Set, in insertion order.

note

Note on the forEach Callback Signature: The full callback signature is (value, key, set). For Set objects, the key is the same as the value, which is a bit redundant but keeps the method consistent with the Map.forEach() signature.

mySet.forEach((value, key) => {
console.log(value === key); // Output: true, true, true
});

for...of vs. forEach(): Key Differences and When to Use Each

While both methods achieve iteration, they have crucial differences that determine which one is better for your specific use case. for...of is generally more powerful.

Featurefor...of LoopforEach() Method
Control FlowSupports break and continue. You can exit the loop early or skip an iteration.Does not support break or continue. It will always run to completion for all elements.
Async/AwaitWorks intuitively with await. The loop will pause for each asynchronous operation.Does not wait for promises. If you use an async callback, forEach will not wait for it to complete before starting the next iteration.
ReadabilityGenerally considered cleaner and more direct for simple loops: for (const item of iterable).Can be more concise for functional chaining, but the callback adds a layer of nesting.
note

Rule of Thumb:

  • Use for...of as your default choice. It is more powerful and flexible.
  • Use forEach() when you have a simple, synchronous operation that you want to apply to every single element without exception.

Practical Example: Finding and Breaking the Loop

This is a classic scenario where for...of is the only correct choice. The script needs to find a specific element in a Set and stop searching as soon as it's found.

let permissions = new Set(['READ', 'WRITE', 'EXECUTE', 'DELETE']);

function hasPermission(permissionToCheck) {
for (let permission of permissions) {
console.log(`Checking: ${permission}`);
if (permission === permissionToCheck) {
return true; // Found it, exit the function (and the loop)
}
}
return false; // Did not find it after checking everything
}

console.log(hasPermission('WRITE'));

Output:

Checking: READ
Checking: WRITE
true
note

This is far more efficient than a forEach() loop, which would have needlessly continued checking "EXECUTE" and "DELETE" even after the item was found.

Conclusion

Iterating over a Set in JavaScript is simple with modern syntax, but choosing the right method is important for writing clean and efficient code.

  • The for...of loop is the recommended best practice for most situations. It is readable, flexible, and correctly handles control flow (break, continue) and async/await.
  • The forEach() method is a good alternative for simple, synchronous operations that must be applied to every element in the Set.

By defaulting to for...of, you ensure your code is ready to handle more complex logic like early exits or asynchronous operations.