Three Ways to Traverse a JavaScript Object
In this article I want to talk about three different ways to traverse an object’s properties in JavaScript and the varying results you can expect when using them. Namely:
for ... in
loopsObject.keys()
Object.getOwnPropertyNames()
And we’re going to look at the differences between them using goats.
So first of all, let’s create a myGoat
object, with a custom goat prototype using Object.create
, and then let’s look at the different ways we can loop over its properties.
Before we get into looping through myGoat’s properties, let’s talk a little about object properties in general. All object properties have attributes assigned to them, one of which is their value. You can view a property’s attributes using the Object.getOwnPropertyDescriptor()
method, or if you want to look at all property attributes you can use Object.getOwnPropertyDescriptors()
.
If we were to have a closer look at myGoat’s ‘coat’ property using Object.getOwnPropertyDescriptor
, we would see this:
We’re interested in the enumerable property, which means ‘countable’. Whether a property is considered enumerable simply means whether this attribute is set to true
or not. A property’s enumerable attribute determines whether it will show up in different types of loops — only enumerable properties will be iterated over in a for ... in
loop or returned from an Object.keys
function call.
All newly-created object properties by default have their enumerable attribute set to true
. To define a non-enumerable property on an object we can use Object.defineProperty
, which lets you determine all attributes of a property, and not just the value.
So let’s add a non-enumerable property to myGoat:
Now this is our myGoat object:
Now that we have the myGoat object defined, let’s talk about those three object traversal methods I mentioned back at the start of the article.
For ... in
loops
A for ... in
loop traverses all enumerable object properties, and the object’s prototype chain. If you want to omit the prototype properties, you will need to filter the loop results through hasOwnProperty
, which limits the operation you’re performing to enumerable properties defined directly on the object.
Object.keys
Calling Object.keys
on an object returns an array containing all the enumerable keys directly defined on the object, so this does not include any properties defined on the prototype chain. These can then be iterated over using any type of array traversal. The same principles apply for Object.values
or Object.entries
.
Object.getOwnPropertyNames
This method will return an array containing all properties directly defined on the object (so not including the prototype chain), regardless of whether these are enumerable or not.
So let’s see what these look like when called on myGoat:
A notable outlier to the above which is worth mentioning is when the object you are traversing has a Symbol
for any of its keys. JavaScript Symbols do not appear in any of the above three methods; instead you would have to separately iterate over these using Object.getOwnPropertySymbols
.
And that’s it! Three different ways to traverse an object’s properties, three slightly different sets of results.