How to use for...of loop in JavaScript
Iterating over collections is a fundamental task in JavaScript, yet choosing the right loop can be confusing for many developers.
With over 25 years of experience in software development and as the creator of CoreUI, I’ve seen iteration patterns evolve from complex for loops to the elegant ES6 for...of syntax.
In modern development, for...of is the most readable and efficient way to traverse iterable objects like arrays, strings, and maps.
This method provides a clean abstraction that avoids the boilerplate of index management while maintaining full support for control statements.
The for...of loop creates a loop iterating over iterable objects, invoking a custom iteration hook with statements to be executed for the value of each distinct property.
const items = ['CoreUI', 'React', 'Angular', 'Vue']
for (const item of items) {
console.log(item)
}
The loop initializes by taking an iterable, such as an array, and assigns the value of the current element to the variable item. It then executes the block of code inside the curly braces. This process repeats automatically for every element in the collection until it reaches the end. Unlike traditional loops, you don’t need to track an index variable or check the array length manually, which significantly reduces the chance of off-by-one errors.
Basic Array Iteration and Logic
When working with UI components in CoreUI, we frequently iterate over configuration arrays or data lists. The for...of loop is perfect here because it allows the use of break and continue, which are not available in methods like .forEach().
// Iterating over a list of CoreUI theme colors
const themeColors = ['primary', 'secondary', 'success', 'danger', 'warning', 'info']
// Use 'const' for the iterator variable if you do not reassign it inside the block
for (const color of themeColors) {
if (color === 'secondary') {
// Skip secondary colors for this specific logic
continue
}
if (color === 'info') {
// Stop processing once we reach the info color
break
}
const className = `btn-${color}`
console.log(`Generating CSS class: ${className}`)
}
// If you need to modify the array during iteration, see:
// /answers/how-to-add-an-item-to-an-array-in-javascript/
In this example, the loop processes each color in the themeColors array. The continue statement allows us to skip the current iteration based on a condition, while break terminates the loop entirely. This level of control is essential for performance-sensitive operations.
Iterating Over Strings
In JavaScript, strings are considered iterables. This means you can use for...of to access every character individually without converting the string into an array first.
// Strings are natively iterable in JavaScript
const brandName = 'CoreUI'
let characterCount = 0
for (const char of brandName) {
console.log(`Processing character: ${char}`)
characterCount++
}
console.log(`Total characters processed: ${characterCount}`)
// For more advanced string manipulation, check:
// /answers/how-to-count-characters-in-a-string-in-javascript/
// /answers/how-to-convert-a-string-to-an-array-in-javascript/
This approach is much cleaner than using a standard for loop with brandName.charAt(i). It handles Unicode characters correctly, which is a common pitfall when dealing with internationalization in modern web applications.
Working with Maps and Sets
Modern JavaScript applications rely heavily on Map and Set objects for state management. The for...of loop is the native way to iterate through these collections, especially when you need to destructure keys and values.
// Maps are excellent for storing component states
const componentStatus = new Map([
['Header', 'active'],
['Sidebar', 'collapsed'],
['Footer', 'visible']
])
// Destructuring is supported directly in the loop head
for (const [component, status] of componentStatus) {
console.log(`The ${component} component is currently ${status}`)
}
// Sets only contain unique values
const uniqueTags = new Set(['ui', 'ux', 'css', 'ui'])
for (const tag of uniqueTags) {
console.log(`Tag: ${tag}`)
}
// Related: /answers/how-to-remove-duplicates-from-an-array-in-javascript/
By destructuring the entry [component, status], the code remains expressive and easy to maintain. This pattern is widely used within the internal logic of CoreUI to manage component registration and property tracking.
Accessing the Index with entries()
One common criticism of for...of is that it doesn’t provide the current index. However, you can easily solve this by using the .entries() method on an array, which returns an iterable of index-value pairs.
const navigationLinks = ['Home', 'Dashboard', 'Settings', 'Profile']
// entries() returns an array [index, value] for each element
for (const [index, link] of navigationLinks.entries()) {
const position = index + 1
console.log(`Link #${position}: ${link}`)
// This is often more readable than a manual index counter
}
// If you just need the total count:
// /answers/how-to-get-the-length-of-an-array-in-javascript/
This technique combines the readability of for...of with the utility of an index. It is particularly useful when building dynamic navigation menus where you need to apply specific logic to the first or last items.
Iterating Over DOM Collections
When manipulating the DOM directly, document.querySelectorAll returns a NodeList. While older browsers required converting this to an array, modern JavaScript allows you to use for...of directly on these collections.
// Selecting all CoreUI buttons in the document
const buttons = document.querySelectorAll('.btn-coreui')
for (const button of buttons) {
// Add an event listener to each button
button.addEventListener('click', (event) => {
console.log('CoreUI button clicked', event.target)
})
// Apply a dynamic style or attribute
if (!button.hasAttribute('role')) {
button.setAttribute('role', 'button')
}
}
Using for...of on a NodeList is efficient because it avoids the overhead of creating a new array instance. This is the preferred method for applying bulk updates to DOM elements in high-performance web interfaces.
Asynchronous Iteration with for await…of
In modern applications, you often need to iterate over data that is fetched asynchronously. The for await...of syntax allows you to loop over an array of promises or an async generator sequentially.
// Simulate fetching data for multiple CoreUI components
async function loadComponents(ids) {
const fetchComponent = (id) => {
return new Promise((resolve) => {
setTimeout(() => resolve({ id, status: 'loaded' }), 500)
})
}
const requests = ids.map(id => fetchComponent(id))
// This loop waits for each promise to resolve before moving to the next
for await (const component of requests) {
console.log(`Component ${component.id} has been ${component.status}`)
}
}
loadComponents([1, 2, 3])
This is a powerful pattern for handling streams of data or ensuring that API requests are processed in a specific order without blocking the main thread. It simplifies the complex logic often associated with Promise.all() or manual recursion.
Best Practice Note:
The for...of loop should be your default choice for iterating over arrays and iterables. While for...in exists, it is designed for iterating over object properties and can lead to unexpected results with arrays because it iterates over keys (strings) rather than values. At CoreUI, we use for...of extensively in our utility functions to ensure cross-browser compatibility and maintainable code. For extremely large arrays where performance is the absolute priority, a traditional for loop might be slightly faster, but for 99% of use cases, the readability of for...of wins.



