/Devops

voltar
/Devops

The difference between for…of and for…in

ByDiego Pinho in

With the ECMAScript 6 (2015) arrival, we’ve gained a bound of iteration for…of. The idea is that we use it to iterate stable objects, that is, the ones that define in their structure – through a generator function, on the property [Symbol.iterator] – how it must be traveled. By default, some objects on JavaScript are already iterable, like Array, Map and the String object itself.

Its use is very simple. Imagine that we have an array of natural numbers and we want to show its values on the console. With the repetition bound for…of, we just have to do the following:

const numbers = [1,2,3,4,5];
 for(let numbers of numbers) {
  console.log(number);
 }

// result: 1, 2, 3, 4, 5

Very simple, right? But what happens is that a lot of people mistake this new type of bound with the already old for…in. Are they the same thing? Let’s put it to test. I’ll do the same iteration of the previous example, only switching the of to in.

const numbers = [1,2,3,4,5];
for(let number in number) {
 console.log(number);
}

// result: 0, 1, 2, 3, 4

Wait, the result was different! But why? Let’s understand what is going on. If we consult the bound definition on the MDN website, we’ll see that the bound for…in “interacts over the enumerated properties of an object, on the original insertion order”. It means that the bound sees the properties, not its values.

It gets easier to understand if we iterate the object House that has three properties: area, height, floors. Take a look at what happens:

const House = {
 area: 1000,
 height: 7,
 floors: 2
}

for(let prop in House) {
 console.log(prop);
}

// Result
// area
// height
// floors

Did you notice the difference? The bound for…of iterates the properties value (on this case), while the bound for…in iterates the properties. But don’t think that it only takes switching in for of that this example will work, because this is what happens:

TypeError: House is not iterable

What does this error mean? As I said in the beginning of the article, the bound for…of searches for the property [Symbol.iterator] of the object to manage iterating it. What this error is telling us, is that it wasn’t defined on this structure. To solve this problem, we can do as following:

const House = {
  area: 1000,
  height: 7,
  floors: 2,
  [Symbol.iterator]: function* (){
	yield this.area;
	yield this.height;
	yield this.floors;
  }
}

Now we have the expected outcome:

for(let prop of House) {
 console.log(prop);
}

// Result
// 1000, 7, 2

Conclusion

The bounds for…of and for…In, despite being very similar, do different things. While the fist searches for the property [Symbol.iterator] insde the structure, that defines how it must be iterated, the second iterates for the enumerated properties of the object. The iterable objects by definition on JavaScript already describe the property so it can show its values (ex: Map, Set, Array), but in any other structure type, this decision is up to the developer.

References:

Leave a comment! 0

read more