# For...of and For...in loops

The `for...in` and `for...of` loops both do the same thing but quite differently, both loop through the enumerable properties of an object but the main difference is that the `for...in` loops through the keys while `for...of` loops through the values.

These iterating over only enumerable properties means that [symbols](https://theninja.blog/symbols-in-java-script/) are ignored because those are non-enumerable.

Both loops are preferable to `for` loops because there's no need to set up an iteration condition or any incrementations on the iterated variable.

## For..in

`for...in` loops should not be used with arrays when `.forEach()` and `for...of` exist. Nobody's really interested in iterating over the keys in arrays because they happen to be the indices.

```javascript
const arr = ['Hello', 'world', true];
for(element in arr){
	console.log(element)
}
// 0
// 1
// 2
```

But in objects, `for..in` might be desirable to check the values of the keys.

```javascript
const obj = {
 	a: 'Hello',
  	b: 'world',
  	c: undefined
}

for(prop in obj){
  	if(obj[prop] === undefined){
      	console.log('undefined value => ' + prop);
    }
}

// undefined value => c
```

## For...of

This is more preferable with working with arrays because in this case, you're iterating over the values and not the keys.

```javascript
const arr = [true, false, 'hello', 'world'];
for(elem of arr){
	console.log(elem);
}

// true
// false
// 'hello'
// 'world'
```

Unfortunately, this is not the same case with objects, `for...of` only works with iterables, and a plain object is not.

```javascript
const obj = {
  	name: 'James',
  	age: 23,
  	sports: ['Soccer', 'Baseball']
}

for(prop of obj){
	console.log(prop)
}

// => Uncaught TypeError: obj is not iterable
```

## Conclusion

If you ever need to get only the values from an object, use [`Object.values`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values) and if you need to iterate over them, you could either use a [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) instead or do this:

```javascript
const obj = {
  	name: 'James',
  	age: 23,
  	sports: ['Soccer', 'Baseball']
}

Object.values(obj).forEach( item => console.log(item));

// 'James'
// 23
// ['Soccer', 'Baseball']
```

If you're not familiar with arrow functions, [check out this article](https://theninja.blog/how-to-use-arrow-functions-in-java-script/).
