for ... inloops
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
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 ... inloops
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 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
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
And that’s it! Three different ways to traverse an object’s properties, three slightly different sets of results.