
Loop Through An Object With JavaScript
In this article, we’ll go over a few of the more common ways to loop through an object in JavaScript. Or more specifically — how to loop through object properties in JavaScript.
When starting out, most developers will at one point or another iterate over an array. With objects in particular, it can be a little bit different.
Let’s go over the reasons for this, as well as explore the various techniques we can utilize to iterate our object properties with.
The standard way – the for…in loop
The standard way to loop through object properties in JavaScript is to use the for...in
loop:
const car = {
make: "Honda",
model: "Civic",
year: 2022
}
for (const key in car) {
if (car.hasOwnProperty(key)) {
console.log(`${key}: ${car[key]}`)
}
}
This for...in
loop is a standard JavaScript loop, and it’s specific purpose is to iterate over the enumerable properties belonging to an object.
The loop is one of the most concise and convenient ways to loop through JavaScript object properties out of the box.
As you can see, when using the for...in
loop, we gain access to each of the object’s keys in the form of the key
const.
To access the value associated with a given key, we can use car[key]
as demonstrated.
What’s hasOwnProperty for?
hasOwnProperty
is a useful function because it allows us to filter out properties that don’t belong directly to the given object.
Typically, these properties would be inherited from other objects — and we may not want them when iterating. In fact, we may not even know about the properties, so it’s often better to filter them out accordingly.
That’s what we’re doing here.
You’ll see hasOwnProperty
used fairly often when iterating in this way. That’s just to stop any nasty surprises or unexpected output.
So in summary, this for...in
approach works fairly well. But let’s take a look through the other techniques we can use.
The (numerous) other ways to loop through an object in JavaScript
There are a number of other approaches we can utilize to loop through object properties in JavaScript.
The other approaches in general work like so: we use a function to convert some aspect of the object (it’s values, or it’s keys, or both) to an array; and then subsequently utilize some functionality upon this (newly returned) array to achieve our desired result.
The first step is to ensure we actually have something we can iterate over directly.
Get something to iterate over
The first step is to take our object, and return the aspects we are interested in in an array format. We can then execute the functionalities we need to upon this resultant array.
Firstly, however, let’s go over why we can’t simply use the forEach
function (or something similar) directly on our object to loop through it’s properties.
Why can’t we use forEach to loop through an object in JavaScript?
The answer to this is straightforward: forEach
is an array method, not an object method.
So attempting to invoke forEach
on an object will simply error. More specifically, we’ll get a TypeError
informing us that forEach
is not a function.
Of course forEach
is an actual function — but on the Array
class, not the Object
one.
You’ll notice the same behaviour with functions like every
and map
.
Given this, it’s clear that we must first prepare our object in to some structure we can iterate over or through.
There are numerous functions we can use in this regard. Let’s take a look at each one, in turn.
Object.keys
First and foremost, we can use the Object.keys
method:
// ["make", "model", "year"]
Object.keys(car)
This method returns an array consisting of all of the keys within the object.
That’s great, it means we can subsequently use forEach
on this entity, now. Or any other array-specific functionality. More on this later.
Object.values
We can also use the Object.values
method:
// ["Honda", "Civic", 2022]
Object.values(car)
As expected, we get another array. Only this time, the array consists of all the values on the object, instead.
Object.entries
Lastly, we can use the entries
method:
// [["make", "Honda], ["model", "Civic"], ["year", 2022]]
Object.entries(car)
Again, another array is returned.
But this time, the array contains both the keys and the values on the object. To be more specific, the entries
method returns an array of arrays. Each array contains the key and the value (aka a key-value pair) based on the object’s properties.
Now, all 3 of these Object
methods provide us with an array. This array contains relevant data from our target object. We can now iterate this array and perform whatever functionality we need to based on it.
In terms of the techniques we can utilize to iterate out arrays, there are two distinct approaches: loops and functions.
Let’s start with the loops.
Loop through an object with… loops
We’ll go over two loops we can use to iterate through the properties of our object.
The for
loop and well as the for...of
loop.
Let’s look at both!
The regular for loop
Of course, you can use a regular for
loop to loop through an object. Or more specifically, to loop through the properties of an object:
const entries = Object.entries(car)
// ["make", "Honda"], ["model", "Civic"], ["year", 2022]
for (let i = 0; i < entries.length; i++) {
consoe.log(entries[i])
}
Functionally this is completely fine. But perhaps a bit cumbersome, however. There are certainly neater ways to handle it.
The for…of loop
The for...of
loop is arguably a bit nicer.
We can use it to iterate over our object’s properties:
// make, model, year
for (const key of Object.keys(car)) {
console.log(key)
}
// Honda, Civic, 2022
for (const value of Object.values(car)) {
console.log(value)
}
The for...of
loop is definitely more concise and compact than the previous for
loop above.
Now let’s take a look at some of the functions we may want to consider.
Loop through an object with functions
As mentioned previously, we’re looking at two different approaches when it comes to looping through objects with JavaScript.
We’ve just touched on using regular loops, now let’s look at using functions instead.
Loop an object with the forEach function
The forEach
function is neat and concise, it simply allows to us to iterate over the object properties and perform whatever functionality is required as per our implementation:
// make, model, year
Object.keys(car).forEach(key => console.log(key))
// Honda, Civic, 2022
Object.values(car).forEach(value => console.log(value))
// ["make", "Honda"], ["model", "Civic"], ["year", 2022]
Object.keys(car).forEach(car => console.log(car))
This approach is fundamentally different to the for
and for...of
approaches above.
Although we can accomplish the same kind of functional output, it’s important to note that forEach
is a function that can be invoked on the array. The for
and for...of
approaches both use loops.
Technically, and semantically, these are different concepts.
What about filter, map and so on?
Maybe you’ve seen other developers looping through object properties using these methods.
For this reason, it’s probably a good idea to briefly touch upon these now to avoid confusion.
Previously, in all other examples, we were either:
- looping directly with a regular loop
- using a function that simply iterates through the object
This is conceptually different to the functionality filter
or map
would provide.
How filter works
Filter creates a new array based on a predicate:
// new array is created: ["Honda"]
Object.values(car).filter(value => value === "Honda")
Based on the logic supplied (in this case, a specific check for the value — value === "Honda"
), a new array is formed.
How map works
Map creates a new array too. It does this based on the result of the provided function.
// new array is created: [true, false, false]
Object.values(car).map(value => value === "Honda")
In this case, we’re returning a boolean value per each iteration of the array. The boolean is either true or false based on the value check I have provided.
Why is this relevant?
This is relevant because, as per your implementation, it may be the case that you’d be better of utilizing one of these methods.
The filter
and map
functions are somewhat similar to forEach
. Only forEach
behaves like a loop, it iterates through every element in our array regardless.
filter
and map
perform specific functionality. We can use these functions coupled with Object.values
, Object.keys
or Object.entries
as demonstrated.
Which approach should I use? forEach vs loops
We’ve covered numerous ways to loop through an object in JavaScript. Now let’s touch on which approach is preferable.
Generally speaking, there is no “best” approach to loop through object properties. It’s all down to personal preference, I don’t think there is a hard and fast answer to cover all scenarios.
However, with that said, let’s weigh up some of the positives of using loops over the forEach
function.
The benefits of using loops
Loops can benefit from control flow
The advantage that the for...of
and the for...in
loops has over the forEach
function is that they support what is known as control flow functionality in the body of the loop.
So we can do things like:
break
the loopcontinue
the loop, so skip the current iterationreturn
from within the loop
And so on.
The makes the loops very powerful, and that’s not something we can easily replicate with the forEach
function.
Loops are faster/more efficient
As per the benchmarking in this great article from LeanyLabs, you can see that loops also perform more efficiently (in general) than the forEach
function.
So generally speaking, unless you have a specific reason to use forEach
— it’s likely the case that utilizing one of the loops will be the better (or at least, more performant) option.
However, with that said — there are benefits associated with the forEach
function, too.
Let’s run through these.
The benefits of using forEach
forEach is perhaps less error-prone
The forEach
function is less error-prone in some regards as it’s called directly on the target array.
With the looping approach, you have to handle this incrementation and iteration yourself.
It’s possible to introduce bugs or unintended consequences if your loop is set up incorrectly.
For this reason, it could be slightly safer to use forEach
on some scenarios.
forEach is more concise
If you compare the usages in this article, you’ll see that the forEach
implementation is a bit more streamline.
The function is invoked directly on the target array, it’s quite concise and easy to read in this regard.
It’s down to developer preference at the end of the day — but there is a good argument to be made with regards to forEach
being clear and easier to interpret.
Handling nested objects
When looping through object properties previously, you may have noticed that if we encounter a property of type object
— we don’t have access to these values or keys as we may want.
Here’s an example:
const person = {
name: "Sarah",
age: 44,
address: {
addressLine1: "Sample Address Line 1",
city: "My City",
postCode: "ABC 123"
}
}
for (const key in person) {
console.log(`${key}: ${person[key]}`)
}
// name: Sarah
// age: 44
// address: [object Object] (???)
So as you can see, we simply receive [object Object]
in place of our object, here.
In this case, that’s not what we want. So we’d need to extract the keys and values (or entries) from the object manually, during our loop.
One of the better ways to handle this is to build a function that we can use recursively, instead.
To clarify what we mean by a “recursive” function: it’s simply a function that calls itself.
A recursive function to loop through (nested) objects
Here’s a simple recursive function we can use to handle the nested objects when iterating through our object properties. The function is comprised of elements we’ve already discussed, such as the use of Object.keys
along with forEach
:
const iterate = (obj) => {
Object.keys(obj).forEach(key => {
console.log(`key: ${key}, value: ${obj[key]}`)
if (typeof obj[key] === "object") {
iterate(obj[key])
}
})
}
Now, we can pass our target object to the iterate
function, and we’ll be able to see the properties of our nested object:
iterate(person)
// key: name, value: Sarah
// key: age, value: 44
// key: address, value: [object Object]
// key: addressLine1, value: Sample Address Line 1
// key: city, value: My City
// key: postCode, value: ABC 123
As per your need, you could of course optionally not output in the iteration that contains the nested [object Object]
. We’re already checking the type
of the value in each iteration; so we can easily skip this output if required by considering this.
You can see the subsequent line contains the actual address data ( key: addressLine1, value: Sample Address Line 1
) that is nested within the referenced object.
So the iterate function works as required. As the function is recursive, it’ll work this way no matter how deeply your nested objects are.
In closing
I hope you’ve enjoyed the article!
Hopefully you’ve gained some insight with regards to how to loop through an object in JavaScript.
To briefly recap what we have covered in the article, from top to bottom:
- Using the
for...in
to loop through an object’s properties - Using
Object.keys
,Object.values
andObject.entries
and then usingforEach
on that result - We touched briefly on
map
andfilter
and explained why those functions may get lumped in with the other techniques in the article - We discussed the pros and cons of
forEach
when compared with the JavaScript loops - We built a recursive function to handle the iteration of nested objects
And that just about concludes this article on how to loop through object properties in JavaScript.
Check back more for similar articles, or alternatively, check out my JavaScript category!