for...in vs for...of in JavaScript
Tags: javascript, beginners, programming, webdev
Published: 2021-08-25 06:14:54

For quite a while, I have been struggling to fully understand the differences between `for...in` and `for...of`. If you found this via Google or the dev.to feed, I can safely assume that you are probably wondering the same thing. `for...in` and `for...of` are the alternative of the `for` loop that we are all familiar with. However, `for...in` and `for...of` are used in different occasions depends on what you are looking for while the `for` loop we know can be used in basically in any situation.

We will first go over the examples/usages, then we'll break down each of them.

## Examples/Usages

### `for` 
```javascript
const arr = [1, 2, 3, 4, 5]

function printArr(arr) {
  for (let i = 0; i < arr.length; i++) {
    console.log(arr[i]);
  }
}

console.log(printArr(arr));

// 1
// 2
// 3
// 4
// 5
```

### `for...in`
```javascript
const obj = { a: 1, b: 2, c: 3 }

function printObj(obj) {
  for (let prop in obj) {
    console.log(`prop: ${prop}`)
    console.log(`obj[prop]: ${obj[prop]}`)
  }
}

console.log(printObj(obj));

// prop: a
// obj[prop]: 1
// prop: b
// obj[prop]: 2
// prop: c
// obj[prop]: 3
```

### `for...of`
```javascript
const arrOf = [1, 2, 3, 4, 5]

function printArrOf(arr) {
  for (let ele of arr) {
    console.log(ele);
  }
}

console.log(printArrOf(arrOf));

// 1
// 2
// 3
// 4
// 5
```

Now you saw how they are used, let's break them down one by one!

---

## Our Dear Best Friend, The `for` Statement

This basic `for` loop can be used anytime when we need iteration in anything.

**Basic Syntax**
```javascript
for ([initialization]; [condition]; [final-expression]) {
  statement
}
```

The iteration usually happens inside the `block` (a.k.a `{}`). We would put multiple statements inside the block for the loop to be executed. You may use `break`, `continue`, etc. to continue or break the `for` loop based on the conditions.

**Example with `break`**
```javascript
for (let i = 0;; i++) {
  console.log(i);
  if (i > 5) break;
}

// Expected Output: 
// 0
// 1
// 2
// 3
// 4
// 5
// 6

// Explanation: The loop breaks when i is larger than 5.
```
Quick Note: All those expressions inside the parentheses are optional.

**Example with `continue`**
```javascript
for (let i = 0; i < 10; i++) {
  if (i === 7) continue;
  else console.log(i);
}

// Expected Output:
// 0
// 1
// 2
// 3
// 4
// 5
// 6
// 8
// 9

// Explanation: if i is equal to 7, we will skip that i and move on to the next index.
```

---

## `for...in`, Protagonist #1

`for...in` loop iterates over all **enumerable properties** of an object. 

If you don't know what enumerable is, I'll do my best to explain what it is. Basically you can think of enumerable property is the `key` of the key-value pair in an object. It will also show up in the `Object.keys()` method. So if we look at our example from the section above...
```javascript
const obj = { a: 1, b: 2, c: 3 }

function printObj(obj) {
  for (let prop in obj) {
    console.log(`prop: ${prop}`)
    console.log(`obj[prop]: ${obj[prop]}`)
  }
}

console.log(printObj(obj));

// prop: a
// obj[prop]: 1
// prop: b
// obj[prop]: 2
// prop: c
// obj[prop]: 3
```

`prop` is the `key` in the key-value pair and that's our enumerable properties. If you have basic understand on how to retrieve the value of an object, we treat the key like index in an array and put it in a square bracket -> `obj[prop]`, like this.

```javascript
const obj = { 
  name: "Megan", 
  age: "do the Math", 
  role: "front-end developer" 
}

for (const property in obj) {
  console.log(property);
}

// Expected Output:
// name
// age
// role
```

So far, our examples are all in object, or `{}` (as array is also an object), it is not recommended/ good practice to use `for...in` to iterate over an array, where the index order is important. 

Yes, array indexes are also enumerable properties but in integer. It behaves quite unpredictably if we use `for...in` to iterate an array. It is not guarantee that the elements are iterated in a specific order. Also, if you want to extend the array by assigning to an index that is beyond the current size of the array, it may not reflect the correct index. Therefore, `for...of`, `forEach`, or `for` loop with a numeric index is a better method to iterate an array. Check out the examples demonstrated in this article below 👇🏻

Further Readings:
- [3 Reasons Why You Shouldn’t Use “for…in” Array Iterations in JavaScript](https://betterprogramming.pub/3-reasons-why-you-shouldnt-use-for-in-array-iterations-in-javascript-8db3f42d8c73) by Johannes Baum (Medium.com)

---

## `for...of`, Protagonist #2

Now here's our second protagonist, `for...of`. In case you don't know, `for...of` is introduced in ES6. `for...of` has become a useful iteration method for a lot of JavaScript developers. `for...of` can iterate over any **iterable objects**. You name it, `String`, `Array`, `Object`...

**String**
```javascript
const name = "Megan";

for (const alphabet of name) {
  console.log(alphabet);
}

// Expected Output:
// M
// e
// g
// a
// n 
```

**Array** (copied from the Example section)
```javascript
const arrOf = [1, 2, 3, 4, 5]

function printArrOf(arr) {
  for (let ele of arr) {
    console.log(ele);
  }
}

// Expected Output:
// 1
// 2
// 3
// 4
// 5
```

**Object** (With the help of `Object.entries()`)
```javascript
const obj = {
  name: "Megan", 
  age: "do the Math", 
  role: "front-end developer" 
};

for (const [key, value] of Object.entries(obj)) {
  console.log(key, value);
  console.log(`${key}: ${value}`);
}

// Expected Output:
// name Megan
// name: Megan
// age do the Math
// age: do the Math
// role front-end developer
// role: front-end developer

// Explanation: the [key, value] is a destructure of the result from Object.entries.
```

**🐧 Sidebar Note 🐧**
`Object.entries()` returns an array of a given object's own enumerable string-keyed property.
```javascript
const obj = {
  name: "Megan", 
  age: "do the Math", 
  role: "front-end developer" 
};

Object.entries(obj)
// [
//  [ 'name', 'Megan' ],
//  [ 'age', 'do the Math' ],
//  [ 'role', 'front-end developer' ]
// ]
```

Further Readings:
- [Demystifying the ES6 ‘for-of’ Loop](https://danielmjung.medium.com/demystifying-the-es6-for-of-loop-9c1a0166d1c6) by Daniel Jung (Medium.com)
- [Why for...of Loop in JavaScript is a Gem](https://dmitripavlutin.com/javascript-for-of/)

---

## When Should We Use Which One? 😯

The purpose of this section is put these two `for` statements "side by side", so we can have a comparison.

Here's a simple way to remember this:
⭐️ Use `for...in` when iterating the object's enumerable string-keyed property pairs. You know the `{ blah1: blah blah, blah2: blah blah blah }`. BUT NOT `ARRAY`!! Remember think of whatever it is logged will be like logging the index of an array, but the string, so if you want to log/return the value, make sure print it with `obj[key]`. 
⭐️ Use `for...of` when iterating over iterable objects: `String`, `Array`, etc.

Further Readings:
- [Difference between for...of and for...in](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of#difference_between_for...of_and_for...in) by MDN

Next time when you are working on something that needs iteration, or just doing your regular Leetcode practice, or even BETTER... in your tech interviews, show off your newly obtained knowledge with `for...of` and `for...in`.

Last but not least... Happy Coding!
<img src="https://media1.giphy.com/media/3o7TKDEhaHWJpBs2Xu/200.gif" alt="coding dance gif" />