How to iterate over a JavaScript object?
Solution 1
For iterating on keys of Arrays, Strings, or Objects, use for .. in
:
for (let key in yourobject) {
console.log(key, yourobject[key]);
}
With ES6, if you need both keys and values simultaneously, do
for (let [key, value] of Object.entries(yourobject)) {
console.log(key, value);
}
To avoid logging inherited properties, check with hasOwnProperty :
for (let key in yourobject) {
if (yourobject.hasOwnProperty(key)) {
console.log(key, yourobject[key]);
}
}
You don't need to check hasOwnProperty
when iterating on keys if you're using a simple object (for example one you made yourself with {}
).
This MDN documentation explains more generally how to deal with objects and their properties.
If you want to do it "in chunks", the best is to extract the keys in an array. As the order isn't guaranteed, this is the proper way. In modern browsers, you can use
let keys = Object.keys(yourobject);
To be more compatible, you'd better do this :
let keys = [];
for (let key in yourobject) {
if (yourobject.hasOwnProperty(key)) keys.push(key);
}
Then you can iterate on your properties by index: yourobject[keys[i]]
:
for (let i=300; i < keys.length && i < 600; i++) {
console.log(keys[i], yourobject[keys[i]]);
}
Solution 2
Here is another iteration solution for modern browsers:
Object.keys(obj)
.filter((k, i) => i >= 100 && i < 300)
.forEach(k => console.log(obj[k]));
Or without the filter function:
Object.keys(obj).forEach((k, i) => {
if (i >= 100 && i < 300) {
console.log(obj[k]);
}
});
However you must consider that properties in JavaScript object are not sorted, i.e. have no order.
Solution 3
Using Object.entries
you do something like this.
// array like object with random key ordering
const anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.entries(anObj)); // [ ['2', 'b'],['7', 'c'],['100', 'a'] ]
The Object.entries() method returns an array of a given object's own enumerable property [key, value]
So you can iterate over the Object and have key
and value
for each of the object and get something like this.
const anObj = { 100: 'a', 2: 'b', 7: 'c' };
Object.entries(anObj).map(obj => {
const key = obj[0];
const value = obj[1];
// do whatever you want with those values.
});
or like this
// Or, using array extras
Object.entries(obj).forEach(([key, value]) => {
console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
});
For a reference have a look at the MDN docs for Object Entries
Solution 4
With the new ES6/ES2015 features, you don't have to use an object anymore to iterate over a hash. You can use a Map. Javascript Maps keep keys in insertion order, meaning you can iterate over them without having to check the hasOwnProperty, which was always really a hack.
Iterate over a map:
var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
for (var [key, value] of myMap) {
console.log(key + " = " + value);
}
// Will show 2 logs; first with "0 = zero" and second with "1 = one"
for (var key of myMap.keys()) {
console.log(key);
}
// Will show 2 logs; first with "0" and second with "1"
for (var value of myMap.values()) {
console.log(value);
}
// Will show 2 logs; first with "zero" and second with "one"
for (var [key, value] of myMap.entries()) {
console.log(key + " = " + value);
}
// Will show 2 logs; first with "0 = zero" and second with "1 = one"
or use forEach:
myMap.forEach(function(value, key) {
console.log(key + " = " + value);
}, myMap)
// Will show 2 logs; first with "0 = zero" and second with "1 = one"
Solution 5
If you want the key and value when iterating, you can use a for...of loop with Object.entries.
const myObj = {a: 1, b: 2}
for (let [key, value] of Object.entries(myObj)) {
console.log(`key=${key} value=${value}`)
}
// output:
// key=a value=1
// key=b value=2
Comments
-
nkuhta almost 2 years
I have an object in JavaScript:
{ abc: '...', bca: '...', zzz: '...', xxx: '...', ccc: '...', // ... }
I want to use a
for
loop to get its properties. And I want to iterate it in parts (not all object properties at once).With a simple array I can do it with a standard
for
loop:for (i = 0; i < 100; i++) { ... } // first part for (i = 100; i < 300; i++) { ... } // second for (i = 300; i < arr.length; i++) { ... } // last
But how to do it with objects?
-
pawel over 11 yearsOP wants to perform this in chunks, not all keys in a single loop.
-
nkuhta over 11 yearsYes. Not full object in one loop.
-
nkuhta over 11 yearsIf I will break loop, it will start from beginning of object next time, that is not right way.
-
Cerbrus over 11 yearsThis does not answer the question on how to iterate through a part of the object.
-
Yoshi over 11 years@Cerbrus The OP allready knows how to iterate an array in parts. Using
keys
from the code given should be enough. -
Cerbrus over 11 years@Yoshi / @dystroy:
Object.keys()
support is IE 9+. For compatibility purposes, I'd suggest not using that. -
Denys Séguret over 11 years@Cerbrus Please read before commenting ! What's not clear in "To be more compatible, you'd better do this" ?
-
Teodor Talov almost 11 years+1 for the console.log() instead of alert() / and for providing the link to MDN
-
am05mhz over 8 yearshi, sorry for bringing old topic, but is there any point of the
if (yourobject.hasOwnProperty(key))
?, as i get the same result with onlykeys.push(key)
, and it should be a little faster without theif
-
Denys Séguret over 8 years@am05mhz As I said, it's useless with most objects. But not for all. Try this: jsbin.com/hirivubuta/1/edit?js,console,output
-
Florian Wendelborn about 7 yearsActually no. This implies that
Object
s are in-order. They're not.If you can make sense of the sentence it worked
only works because of implementation details. It's not guaranteed to work at all. Also you shouldn't TitleCase your functions & variables. That's forclass
es. -
pungggi almost 6 yearsforEach is the prefered one
-
CONTRACT SAYS I'M RIGHT almost 6 yearsupvoted just for your statement in the first sentence. Even though it'd be better if the value was first parameter, the index or key second parameter, and the object third parameter, to make it more like the array forEach(). I'd recommend recommending lodash though.
-
Steven Spungin almost 6 yearsI do like the idea of the (value, key) order. That is how a library such as Vue does it too. Because the object is the context, it do think it belongs as the first parameter though. That's pretty standard for functional programming.
-
CONTRACT SAYS I'M RIGHT almost 6 yearsI would agree here, were it not for ECMA-262 defining an array as an object having a forEach(), map(), reduce(), filter(), which all take callbacks receiving the order [value, index, array]. An object in JS can be understood as just another collection; and then these methods become unified in their parameters of [value, key|index, context] (this is what lodash and underscore are doing). In my opinion, this "unified collection" protocol is just stronger. Also, the object isn't the context: you can set
this
to whatever you like for the callback, as the callback has its own context. -
Steven Spungin almost 6 yearsPerhaps I should have used the work receiver instead of this. Anyway still a PITA; I would welcome the parameters in any order.
-
CONTRACT SAYS I'M RIGHT almost 6 yearsOh, I see that we might have misunderstood each other. I was always commenting about the callback parameters and their order, not about the actual
objectForEach
function. Sorry if that was confusing. -
choz over 3 years9 years developing in JS, and I always doubt myself with
for..of
andfor..in
, and ended up coming here. -
dotancohen almost 2 years@choz: I remember which method to use with the mnemonic "Javascript iteration is foreign" which sounds like "for . .in". I myself authored a long post on the topic and still need the mnemonic.
-
Adam almost 2 yearsIts recommended to avoid for...in, see stackoverflow.com/questions/3010840/… for details