Search justacoding.blog. [Enter] to search. Click anywhere to close.

October 20th, 2021

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 loop
  • continue the loop, so skip the current iteration
  • return 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 and Object.entries and then using forEach on that result
  • We touched briefly on map and filter 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!

Thanks for reading!

Have any questions? Ping me over at @justacodingblog
← Back to blog