How to use for...in loop in JavaScript
Iterating over object properties is a fundamental task in JavaScript, yet many developers struggle with the nuances of property enumerability and prototype inheritance.
With over 25 years of experience in software development and as the creator of CoreUI, I’ve utilized various iteration patterns to build high-performance UI components since the early days of the web.
The for...in loop remains the most direct way to traverse the enumerable string properties of an object, including those inherited from its prototype chain.
Understanding when and how to use this loop is critical for writing clean, efficient, and bug-free code in modern JavaScript environments.
Use the for...in loop to iterate over all enumerable string properties of an object, including inherited ones.
const user = { name: 'Łukasz', role: 'Developer', project: 'CoreUI' }
for (const key in user) {
console.log(`${key}: ${user[key]}`)
}
This code snippet initializes a constant key for each property name found in the user object. During each iteration, we access the property value using the bracket notation user[key]. This allows us to dynamically read every key-value pair stored within the object without knowing the property names beforehand.
Basic Object Iteration
When working with data objects, for...in provides a straightforward syntax for extracting keys. This is particularly useful when you receive dynamic JSON responses from an API where the keys might vary based on the user’s permissions or settings.
const settings = {
theme: 'dark',
notifications: true,
sidebarMinimized: false
}
function logSettings(config) {
for (const setting in config) {
const value = config[setting]
console.log('Setting:', setting, 'is set to:', value)
}
}
logSettings(settings)
In this example, the loop goes through each property defined in the settings object. It is important to note that the order of iteration in a for...in loop is not strictly guaranteed to be the order in which properties were defined, although modern engines typically follow a predictable sequence for string keys.
Filtering Inherited Properties
A common pitfall with for...in is that it iterates over inherited properties found in the prototype chain. To ensure you are only interacting with properties defined directly on the object itself, you should use the Object.hasOwn() method (the modern replacement for hasOwnProperty).
const baseConfig = { version: '1.0.0' }
const customConfig = Object.create(baseConfig)
customConfig.theme = 'CoreUI-Pro'
for (const key in customConfig) {
if (Object.hasOwn(customConfig, key)) {
console.log('Own property found:', key, customConfig[key])
} else {
console.log('Inherited property skipped:', key)
}
}
By wrapping the logic inside an if statement that checks Object.hasOwn(), we prevent the loop from processing the version property, which resides on baseConfig. This is the same approach we use in CoreUI core logic to ensure component configurations aren’t polluted by global object extensions.
Modifying Values During Iteration
You can use the for...in loop to transform an object by iterating over its keys and updating values. This is often cleaner than converting the object to an array and back again when you only need to perform simple mutations.
const pricing = {
basic: 10,
pro: 25,
enterprise: 100
}
const discount = 0.9
for (const plan in pricing) {
// Apply a 10% discount to each plan
pricing[plan] = pricing[plan] * discount
}
console.log('New pricing:', pricing)
In this scenario, we use the key to access the original value, apply a calculation, and then assign the result back to the same property. This method is efficient for small to medium-sized objects where creating a new object structure might be unnecessary overhead.
Using for…in with CoreUI Configuration
In the context of CoreUI, we often use objects to manage component state. Iterating through these state objects allows us to apply classes or styles dynamically based on the current configuration.
const componentState = {
active: true,
disabled: false,
visible: true,
loading: false
}
let classList = 'c-component'
for (const state in componentState) {
if (componentState[state] === true) {
classList += ` is-${state}`
}
}
// Result: 'c-component is-active is-visible'
console.log('Generated classes:', classList)
This logic iterates through the componentState and appends a class name only if the value is true. It’s a performant way to build dynamic strings for DOM manipulation without relying on heavy external dependencies.
Why for…in is Not for Arrays
While it is technically possible to use for...in on an array, it is strongly discouraged. The loop iterates over indices as strings (‘0’, ‘1’, ‘2’) and may pick up unexpected properties if the array object has been modified or extended.
const colors = ['red', 'green', 'blue']
// Adding a custom property to the array object
colors.customLabel = 'primary'
console.log('Iterating array with for...in:')
for (const index in colors) {
console.log(index, colors[index])
}
// This will log '0', '1', '2' AND 'customLabel'
Instead of using for...in for arrays, you should use for...of or standard array methods. If you need to manipulate arrays, consider checking out how to get the length of an array in JavaScript or how to check if an array contains a value in JavaScript for more appropriate patterns.
Performance and Enumerability
Performance-wise, for...in is generally slower than Object.keys() combined with a forEach or for...of loop because of the prototype chain lookups. However, for most UI-level tasks, the difference is negligible.
const largeObject = { /* ... many properties ... */ }
// Optimization tip:
// If you only care about keys, this is often faster
const keys = Object.keys(largeObject)
for (let i = 0; i < keys.length; i++) {
const key = keys[i]
const value = largeObject[key]
// Process value
}
The for...in loop only sees enumerable properties. If a property is defined using Object.defineProperty with enumerable: false, it will be skipped. This is a useful feature when you want to “hide” certain metadata on an object that shouldn’t appear during standard iteration.
Best Practice Note:
Always use for...in for objects and for...of for arrays. When using for...in, always pair it with Object.hasOwn() or hasOwnProperty to avoid processing inherited properties that could break your logic. This is the same defensive programming standard we maintain across all CoreUI libraries to ensure maximum reliability and compatibility across different JavaScript environments.



