What is for...in statement

Enumerable is an attribute that determines whether or not a property can be accessed when the object properties are enumerated using the loop. Objects in JavaScript, unlike arrays, do not belong to collections. That’s why it’s not possible to loop through an object with the help of a common for…of cycle (you will get a Type Error in this case).

However, you can still face a situation when a command like this needs to be performed. For example, you want to print all the properties of your object or they can be added dynamically so that their names can get changed.

Yet, using for...in statement, you can quickly and effortlessly loop through an object’s properties with just one command. Let’s review this command’s syntax:

for (variable in object) {
    // statements
 }

In this code, a variable stands for itself - an element, an array, or the property of a particular object. In turn, an object is a valid and operating name of an object, the properties of which will be iterated through. We’ve intentionally left a comment regarding statements since these are code statements used to execute each pass through the loop.

For…in and strings

It’s no surprise that such a widely-used statement can also sufficiently work with strings. We’ll show you how this approach loops to iterate over string values in the following example. Take a look:

const string = 'Test';
 // using for...in loop
for (let i in string) {
    console.log(string[i]);
}

We’ve intentionally left the comment to illustrate a proper placement of a loop. Your console output will look like that:

T
e
s
t

Please note that the for…in loop also saves string’s (or array’s) parameters, which are best seen when viewing capitalization and the proper use of upper cases.

For…in and objects

There are several ways to loop through an object in JavaScript. The easiest of them is the use of for…in construction which is very similar to a regular cycle. You can find the syntax in the example below.

const dog = {
  name: "Max",
  color: "brown"
};
for (const p in dog) {
  console.log(p + ": " + dog[p]);
}
// name: Max
// color: brown

In case you want to find out the amount of properties in a certain object, you can put a counter inside the loop like in the following code.

let count = 0;
for (const p in dog) {
  count++;
}
console.log(count); // logs 2

Keep in mind that not always for…in cycle shows you the properties in the same order as they were added to the object. This rule works for non-numeric strings only. And if the name of your property is a number or a numeric string, all modern web browsers will sort such properties for the purpose of some inner optimization.

In the example below there is an object of several square roots created. You may expect for…in loop to show you the properties in the same order as they are specified in the object. However, the JS interpreter will recognize that the strings are numeric, so they will be printed vice versa.

const roots = {
 "144" : "12",
 "121" : "11",
 "100" : "10"
 };

for (const p in roots) {
console.log(p);
}
// 100, 121, 144

If you desperately need to print the properties in the same order, you have to make them non-numeric. For example, you can add parentheses or use any other sign while giving a name to your property - “(144)” : “12”. 

Despite its simplicity, this cycle does not really work in the same way that you can expect. It will show you not only the properties added to the object, but also the properties of its prototype. That’s why for…in cycle is used much less frequently. 

In order to solve this problem you need to check if each property belongs to the object. You can do that by means of the special function hasOwnProperty(). It returns true if the object has a non-inherited property with the specified name. And if there is no such property in the object at all, or it is inherited from the prototype, false will be returned as a result. The code below illustrates the use of hasOwnProperty() method.

for (const p in dog)
{
  if(dog.hasOwnProperty(p)) {
  console.log(p + ": " + dog[p]); }
} 

Alternative solutions

More common way to loop through an object in JavaScript is going through its keys. You can get them using the Object.keys() method which returns an array of the names of properties. The use of for…of loop allows you to go through it, filter, receive the needed values, print them or anything else.

const dog = {
  name: "Max",
  color: "brown"
};
console.log(Object.keys(dog)); // logs ['name', 'color']

If you are not going to use the keys of your object, you can get its values immediately using the Object.values() method as illustrated in the following example.

const dog = {
  name: "Max",
  color: "brown"
};
console.log(Object.values(dog)); // logs ['Max', 'brown']

Finally, there is a simple way to get keys and values returned together. That is the use of Object.entries() method. It will return you an array of pairs (a property and its value). Then the same for…of loop will help you to get access to each element easily. 

In the code below the variable entries consists of two arrays (because there are two properties in the object) and each of them has two elements in it (a property and its value). 

const entries = Object.entries(dog);
for ([key, value] of entries)
{
  console.log(key + ": " + value);
}

Objects in JavaScript can contain either enumerable or non-enumerable properties depending on the value of their inner flag [[Enumerable]]. If its value is true, the property is called enumerable. It happens by default for the properties created by simple assigning or initialization. The properties defined by Object.defineProperty() become non-enumerable automatically.

Note that for…in loop, as well as Object.keys() method, can get access to enumerable properties only. However, there is another method returning an array of properties of both types (enumerable and non-enumerable) that belong to the object only (not inherited from its prototype). That is Object.getOwnPropertyNames()

In the code below an array of 3 elements is created. When you call Object.keys() or Object.getPropertyNames() methods using an array, it will be converted to an object first. This example illustrates how the second method returns 4 properties instead of 3. Non-enumerable property length is also included.

const array = [1, 2, 3];
console.log(Object.keys(array)); // logs "['0', '1', '2']"
console.log(Object.getOwnPropertyNames(array)); // logs "['0', '1', '2', 'length']"

The method described above does not add the properties which belong to Symbol data type. In order to get those returned you will need to use getOwnPropertySymbols().