Fruity For Loops Yeah!
Tags: beginners, javascript, webdev, forloop
Published: 2020-11-29 03:00:43

Switching my language from Ruby to JavaScript left me in such a confusing stage, especially the difference in syntax. One of my most used iteration methods is the loop, which is available in both ruby and JS. Loops offer a quick and easy way to skim through iterable Objects. There are several statements for loops (for statement, do...while statement, while statement, break statement, etc). Today, I'll discuss `for`, `for...in` and `for...of` statements usage. This blog should give you an overview of how to use each statement correctly and effectively.

###**1. for Statement:**
The most common for loop and easiest to use in my opinion. A for loop executes the same block of code until a specified condition evaluates to false. 

**Syntax:**

```javascript
for ([initialExpression]; [conditionExpression]; [incrementExpression]){
  //code block to be executed
}
```


**There are three main expressions in a for loop:**
* **initialExpression:** 
initialExpression initializes a counter variable, typically by using `var` or `let`. Variables being declared using `let` are local to the statement. initialExpression is executed (one time) before the execution of the code block and its result will be discarded.


* **conditionExpression:**
conditionExpression is evaluated to decide if the code block is being executed. If this expression evaluated to be true, the for loop will continue, the code block will be executed. If the result returns false, the for loop terminates.

* **incrementExpression:**
Typically used to increase or adjust the counter variable before another loop is executed. To execute multiple statements, use a block statement `{...}` to group those statements.

**When a for loop is executed, these following steps occur:** 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/k8jcf9zkzd5xliljidvt.png)
 
**Example:**

In order to return an array of only even numbers, we can use a for loop:
```javascript
const num = [1, 5, 7, 8, 9, 10]
let even = []

for(let i = 0; i < num.length; i++) {
    if (num[i] % 2 === 0) {
        even.push(num[i])
    }
}
return even
//[ 8, 10 ]
```
So what's happening in our `for` loop?

1. We initialize `i` as a counter variable starting from 0.  
2. Condition is being evaluated. In this case, `num.length` is 6 so as long as `i`'s value is less than 6, our `for` loop continues.
3. Our code block is executed since the condition is evaluated to be true.
4. Counter variable being incremented before the next `for` loop start, which brings `i`'s value to 1. Then back to step 2 until `i`'s value = 6 and the condition is evaluated to be false. The loop terminates.
5. Return the `even` array. 


###**2. For..in Statement:**
A handy for loop that is used to loop over [enumerables](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties) (JSON objects, a bag of Skittles are enumerables). Not recommended to be used with arrays where index order is important.

**Syntax:**

```javascript
for(let key in object) {
  //code block to be executed
}
```

Our object looks like this:
```javascript
let object = {
    key: value
    ...
}
```
or
```javascript
object.key = value
```

**Crucial parameters:**
* **key** :
get assigned by properties of the object each time a for loop is executed.
* **object** :
a specified object that non-symbol properties will get iterated over.

**Example:**
* Ability to iterate over an object's property and access the property's value:
```javascript
const profile = {
    first_name: 'Jane',
    last_name: 'Sparkling',
    sex: 'F',
    dob: '05/23/1968'
};

for(let p in profile) {
    console.log(p + ': ' + profile[p])
}
```
On console: 
```javascript
first_name: Jane
last_name: Sparkling
sex: F
dob: 05/23/1968
```
What's happening?
1. We declare `p` (as properties) of our profile Object. So in this case, `p` can be `first_name`/`last_name`/`sex`/`dob` in our loop.
2. When we console.log our result, `p` will only return the Object's property, so in order to access the value, we have to call `profile[p]` to get that property's value.

* Iterate through an array where the element's index is not important. `for..in` loop only returns truthy values:
```javascript
let arr = []
arr[1] = 3
arr[2] = 4
arr[4] = 5
//empty, 3, 4, empty, 5

for(num in arr){
    console.log(arr[num])
}
```
Result: 
```javascript
3
4
5
```
If we used a `for` loop: 
```javascript
for (let i = 0; i < arr.length; i++) {
    console.log(arr[i]);    
}
```
The result will also include falsy values:
```javascript
undefined
3
4
undefined
5
```

###**3. For..of Statement:**
`for..of` will loop through values of an [iterable object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator) (JSON array, a line in DMV are iterables). Can be used to handle arrays, DOM collection, etc.

**Syntax:**

```javascript
for(let variable of iterable) {
  //code block to be executed
}
```
**Crucial parameters:**
* **variable:**
On each iteration, a property's value will be assigned to a variable. A variable can be declared by using `let`, `const` or `var`.
* **iterable:** 
An iterable Object.

**Example:**
* Iterating over an array: 
```javascript
const nums = [21, 17, 18, 22, 30]

for(const num of nums){
    console.log(num)
}
//21, 17, 18, 22, 30
```
or you can also use `let` to declare a variable if you need to change its value later:
```javascript
const nums = [21, 17, 18, 22, 30]

for(let num of nums){
    num *= 2
    console.log(num)
}
//42, 34, 36, 44, 60
```

* Iterating over a DOM Collection to add a <img> tag with image URL fetched from an API:
```javascript
//json["message"] is an array of image URL
for(const img of json["message"]) {
    let pic = document.createElement('img')
    pic.setAttribute('src', img)
    image.appendChild(pic)
}
// in HTML file:
//<img src="https://images.dog.ceo/breeds/dane-great/n02109047_1672.jpg">
```

* Iterating over a string: 
```javascript
const iterable = 'boo';

for (const value of iterable) {
  console.log(value);
}
//b
//o
//o
```

###**4. `for..in` and `for..of` comparison:**
Both `for..in` and `for..of` iterates over objects, but the main difference is the way it iterates:

**Example** from [for...of - javascript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of)
```javascript
const iterable = [3, 5, 7];
iterable.foo = 'hello';
//[3, 5, 7, foo: "hello"]

for (const i in iterable) {
  console.log(i); 
}
// logs 0, 1, 2, foo
```
The `for..in` loop iterates over enumerable properties of an object. So the reason it doesn't log `3`, `5`, `7` or `hello`  because these are not enumerable properties, but in fact, they are values. It logs array indexes, which are enumerable properties with integer names.
```javascript
const iterable = [3, 5, 7];
iterable.foo = 'hello';
//[3, 5, 7, foo: "hello"]

for (const i of iterable) {
  console.log(i);
}
// logs 3, 5, 7
```

The `for..of` loop will iterate over properties and logs its values. Return variables will only be the value and none of the properties.

**Bonus:**
In order to log all properties' values:
```javascript
const iterable = [3, 5, 7];
iterable.foo = 'hello';
//[3, 5, 7, foo: "hello"]

for (const i in iterable) {
  console.log(iterable[i]); 
}
// logs 3, 5, 7, hello
```

###**Helpful Resources**:
- [for..in](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in#Array_iteration_and_for...in)
- [for..of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of)
- [loops and iterations](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration)
- A deeper comparison between `for..in` and `for..of` [here](https://medium.com/better-programming/what-is-the-difference-between-for-in-and-for-of-in-javascript-650952654e97)