How do I loop through or enumerate a JavaScript object?
Under ECMAScript 5, you can combine Object.keys()
and Array.prototype.forEach()
:
var obj = { first: "John", last: "Doe" };
Object.keys(obj).forEach(function(key) {
console.log(key, obj[key]);
});
ECMAScript 6 adds for...of
:
for (const key of Object.keys(obj)) {
console.log(key, obj[key]);
}
ECMAScript 8 adds Object.entries()
which avoids having to look up each value in the original object:
Object.entries(obj).forEach(
([key, value]) => console.log(key, value)
);
You can combine for...of
, destructuring, and Object.entries
:
for (const [key, value] of Object.entries(obj)) {
console.log(key, value);
}
Both Object.keys()
and Object.entries()
iterate properties in the same order as a for...in
loop but ignore the prototype chain. Only the object's own enumerable properties are iterated.
You have to use the for-in loop
But be very careful when using this kind of loop, because this will loop all the properties along the prototype chain.
Therefore, when using for-in loops, always make use of the hasOwnProperty
method to determine if the current property in iteration is really a property of the object you're checking on:
for (var prop in p) {
if (!p.hasOwnProperty(prop)) {
//The current property is not a direct property of p
continue;
}
//Do your logic with the property here
}
You can use the for-in
loop as shown by others. However, you also have to make sure that the key you get is an actual property of an object, and doesn't come from the prototype.
Here is the snippet:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
for (var key in p) {
if (p.hasOwnProperty(key)) {
console.log(key + " -> " + p[key]);
}
}
For-of with Object.keys() alternative:
var p = {
0: "value1",
"b": "value2",
key: "value3"
};
for (var key of Object.keys(p)) {
console.log(key + " -> " + p[key])
}
Notice the use of for-of
instead of for-in
, if not used it will return undefined on named properties, and Object.keys()
ensures the use of only the object's own properties without the whole prototype-chain properties
Using the new Object.entries()
method:
Note: This method is not supported natively by Internet Explorer. You may consider using a Polyfill for older browsers.
const p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
for (let [key, value] of Object.entries(p)) {
console.log(`${key}: ${value}`);
}
The question won't be complete if we don't mention about alternative methods for looping through objects.
Nowadays many well known JavaScript libraries provide their own methods for iterating over collections, i.e. over arrays, objects, and array-like objects. These methods are convenient to use and are entirely compatible with any browser.
If you work with jQuery, you may use
jQuery.each()
method. It can be used to seamlessly iterate over both objects and arrays:$.each(obj, function(key, value) { console.log(key, value); });
In Underscore.js you can find method
_.each()
, which iterates over a list of elements, yielding each in turn to a supplied function (pay attention to the order of arguments in iteratee function!):_.each(obj, function(value, key) { console.log(key, value); });
Lo-Dash provides several methods for iterating over object properties. Basic
_.forEach()
(or it's alias_.each()
) is useful for looping through both objects and arrays, however (!) objects withlength
property are treated like arrays, and to avoid this behavior it is suggested to use_.forIn()
and_.forOwn()
methods (these also havevalue
argument coming first):_.forIn(obj, function(value, key) { console.log(key, value); });
_.forIn()
iterates over own and inherited enumerable properties of an object, while_.forOwn()
iterates only over own properties of an object (basically checking againsthasOwnProperty
function). For simple objects and object literals any of these methods will work fine.
Generally all described methods have the same behaviour with any supplied objects. Besides using native for..in
loop will usually be faster than any abstraction, such as jQuery.each()
, these methods are considerably easier to use, require less coding and provide better error handling.