Reviewing Eloquent Javascript #Chpt5
Tags: javascript, eloquentjs, beginners, review
Published: 2020-12-11 05:52:47

**In this blog, I will write on my learnings from the Eloquent Javascript Book's Chapter 4: Data Structures: Objects and Arrays.**

Here's the PDF for Eloquent Javascript Book's **[Chapter 5](https://eloquentjavascript.net/05_higher_order.html).**

## **TOC:**

1. **Back in Days of Programming**
2. **Abstraction**
3. **What is Functional Programming**
4. **First-Order Function.**
5. **Abstracting repetition.**
6. **Higher-order functions**
    - **Array.prototype.forEach()**
    - **Array.prototype.filter()**
    - **Array.prototype.map()**
    - **Array.prototype.reduce()**
    - **Array.prototype.sort()**

### **Back in Days of Programming**

- In the early days a lot of the programming languages were what we would call **procedural**.  They would go from **top to bottom** and those is kind of programs were easy to understand but as your code gets more and more complex then it gets a bit difficult because it's hard to know when something goes wrong or what exactly went wrong?

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

- So in a lot of places **complexity is always the enemy**.  As humans we have pretty capable brains but we can only hold so much information in it at one time. The  more complex a program gets the more likely it is that it will crash and it will have problems and it.
- So along came this concept of **Object Oriented Programming** and a lot of people really loved the concept.  So languages that became really big such as **Java**, **Swift** or in fact **Javascript** which we're working  with, are all **Object Oriented Programming languages.**
- In object-oriented programming, **abstraction** is one of the four central principles (along with **encapsulation**, **inheritance**, and **polymorphism**).

### **Abstraction:**

- **Abstraction** is the process of showing only **essential/necessary features** ( displaying only the important functionality to the users ) of an **entity/object** to the outside world and **hide** the other **irrelevant information** (i.e the implementation details).

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/yxbmn860tq71epnbepow.PNG)

- For example to open your TV we only have a power button, It is not required to understand how infra-red waves are getting generated in TV remote control.
- Abstraction helps us to **reduce code duplication,** what abstraction is all about being able to build more **complex systems** by creating **smaller pieces** that have a defined job or defined role so that you can actually manage the complexity.

### **What is Functional Programming**

- In most simple term, **Functional Programming** is a form of programming in which you can pass **functions as parameters to other functions** and also **return them as values**. In functional programming, we think and code in **terms of functions**.
- **JavaScript**, **Haskell**, **Clojure**, **Scala**, are some of the languages that implement functional programming. Functional Programming is also using in **AI** and **Machine Learning.**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/bp0zi67njemxhi1szwks.jpg)

### First-Order Function:

- **First order functions** are functions that **take data as input** and then utilize ( work ) on that data. These functions are used to store behaviors that act on data alone. These functions in Javascript   are treated like **any other variable**.
- Example:

    ```jsx

     function greet(text) {
       console.log(text);
     }
     greet("Good Morning");   
     // Good Morning              

     var talk = greet;  // Storing in a variable
     talk("Hi");

    ```

- Example 2:

    ```jsx
    	
     var sum = function(num1, num2) {
       return num1 + num2;
     }; 

     console.log(sum(10, 20));
     // 30

    ```

### **Abstracting repetition:**

- **Abstracting repetition** is nothing but we will "**abstract**" the code that is repeating (running number of times) in a function.
- Example: **For loops** are used when we are doing something number of times.

    ```jsx

     for (let i = 0; i < 10; i++) {
       console.log(i);
     }

    ```

- Your we are consoling ( repeating ) the counter variable `i` 10 number of times.
- So let's abstract it for looping through the variable `i` for "**n**" number of times.

    ```jsx

     function repeatLog(n) {
       for (let i = 0; i < n; i++) {
         console.log(i);
       }
     }

    ```

- Example 2:

    ```jsx

     function repeat(n, action) {
       for (let i = 0; i < n; i++) {
         action(i);
       }
     }

     let labels = [];
      repeat(5, i => {
        labels.push(`Unit ${i + 1}`);
     });
     console.log(labels);
     // → ["Unit 1", "Unit 2", "Unit 3", "Unit 4", "Unit 5"]

    ```

- To explain what's happening first we will make this function a bit more readable.

    ```jsx

     function repeat(n, action) {
       for (let counter = 0; counter < n; counter++) {
         action(counter);
       }
     }

     let labels = [];
     repeat(5, function(num){                  //Here, we are calling repeat() function
    		labels.push(`Unit ${num + 1}`);
     });
     console.log(labels);
     // → ["Unit 1", "Unit 2", "Unit 3", "Unit 4", "Unit 5"]

    ```

1. When calling the repeat function we pass **two parameters** to it `n` the **number till the loop will run** and `action` that is the function that will a**dd elements in the variable** `label`.
2. So the repeat function will look something like this

    ```jsx
    	
     function repeat(5, action) {
       for (let counter = 0; counter < 5; counter++) {
         function(counter){                  
    		   labels.push(`Unit ${num + 1}`);
         };
       }
     }

    ```

3. After that, the loop will run till `counter` is less that 5 i.e. 4 .

    ```jsx

     Iteration 0: action(0) -> labels.push(`Unit ${0 + 1}`);
     Iteration 1: action(1) -> labels.push(`Unit ${1 + 1}`);
     Iteration 2: action(2) -> labels.push(`Unit ${2 + 1}`);
     Iteration 3: action(3) -> labels.push(`Unit ${3 + 1}`);
     Iteration 4: action(4) -> labels.push(`Unit ${4 + 1}`);

    ```

### Higher-order functions

- **Higher-order functions** are functions that either **take a function as an argument** or **return a function after execution**. This is extremely important because it means that programmers can **abstract over actions**, not just **data** ( values ).
- The greatest benefit of Higher-order functions is **reusability**.
- Also, taking an other function as an argument is often referred as a callback function, because it is called back by the higher-order function.
- For example, `forEach()`, `map()` , `filter()` , `reduce()` and `sort()` are some of the Higher-Order functions built into the language.

Here’s a list of student. We’re going to do some calculations with their information.

```jsx
 
const studentDetails = [
     { studentName: "Prerana", interests: "Finance", startingYear: 1981, endingYear: 2004 },
     { studentName: "Sidhhi", interests: "Retail", startingYear: 1992, endingYear: 2008 },
     { studentName: "Ritu", interests: "Auto", startingYear: 1999, endingYear: 2007 },
     { studentName: "Pratik", interests: "Retail", startingYear: 1989, endingYear: 2010 },
     { studentName: "Harsh", interests: "Technology", startingYear: 2009, endingYear: 2014 },
     { studentName: "Om", interests: "Finance", startingYear: 1987, endingYear: 2010 },
     { studentName: "Vijay", interests: "Auto", startingYear: 1986, endingYear: 1996 },
     { studentName: "Hasnain", interests: "Technology", startingYear: 2011, endingYear: 2016 },
     { studentName: "Bhargav", interests: "Retail", startingYear: 1981, endingYear: 1989 }
  ];

```

```jsx
const ages = [33, 12, 20, 16, 5, 54, 21, 44, 61, 13, 15, 45, 25, 64, 32];
```

### 1. **Array.prototype.forEach()**

- **forEach() method** is the better way to loop through an error rather than the traditional for loop.
- Example using `for` loop:

    ```jsx
    	
     for (let i = 0; i < studentDetails.length; i++) {
         console.log( 'index: ' + i + 'student' + studentDetails[i].studentName);
     }

    ```

- Example using `forEach()` method:

    ```jsx
    	
     studentDetails.forEach(function(student, index) {
         console.log('index: ' + index + 'student' + student.studentName);
     });

    ```

- Both the functions will output the same results.
- **Foreach takes a callback function and executes the function once for each array element.**
- Basically, it loop through every element of array one by one, and perform some actions on them. Also it is **less error prone** and **easier to read**.
- Note: **index is optional** so, can it run without it.
- Remember: When you perform certain action using ForEach loop it changes the data on the **original array**.
- forEach() expects a **synchronous function** it does not wait for **promises**.

### 2.  **Array.prototype.filter()**

- **Filter method** creates a **new array** with element that pass the test applied by the callback function. We use this method, to filter a given array according to some condition.
- Fliter method can be used for particular usecases where the user wants to identify certain items in an array that share a common characteristic.
- Let's take our `ages` array and try to fliter out age's between 21 and 51.
- Using `for` loop

    ```jsx

     let drive = [];
     for (let i = 0; i < ages.length; i++) {
         if (ages[i] >= 21 && ages[i] <=51) {
             drive.push(ages[i]);
         }
     }
     console.log(drive);
     // [33, 21, 44, 45, 25, 32]

    ```

- Using `fliter()` method

    ```jsx

     const drive = ages.filter(function(age) {
        if (age >= 21 && age <= 51) {
            return true;
        }
     });
     console.log(drive);
     // [33, 21, 44, 45, 25, 32]

    ```

- Using `fliter()` method with Arrow syntax (ES6):

    ```jsx

     const drive = ages.filter(age => (age >= 21 && age <= 51));
     console.log(drive);
     // [33, 21, 44, 45, 25, 32]

    ```

- Let's take our `studentDetails` array and try to fliter out students that were in the college for 10 years and above.
- Using `for` loop

    ```jsx

     let tenYearsUsingFor = [];
     for (let i = 0; i < studentDetails.length; i++) {
         if (studentDetails[i].endingYear - studentDetails[i].startingYear >= 10) {
             tenYearsUsingFor.push(studentDetails[i]);
         }
     }
     console.log(tenYearsUsingFor);

    ```

- Using `fliter()` method

    ```jsx

     const tenYears = studentDetails.filter(function(student){
       if (student.endingYear - student.startingYear >= 10) {
            return true;
        }
     });
     console.log(tenYears);

    ```

- Using `fliter()` method with Arrow syntax (ES6):

    ```jsx

     const tenYears = studentDetails.filter(student => (student.endingYear - student.startingYear >= 10));
     console.log(tenYears);
    ```

### 3.  **Array.prototype.map()**

- The `map()` method creates a **new array** with the results of calling a function for every array element.
- The `map()` method calls the provided function once for each element in an array, in order.
- Lets try to get Square root of all the age's from the `ages` array:
- Using `for` Loop:

    ```jsx

     let rootsUsingFor = [];
     for (let i = 0; i < ages.length; i++) {
         rootsUsingFor.push(Math.floor(Math.sqrt(ages[i])));
     }
     console.log(rootsUsingFor);
    // [5, 3, 4, 4, 2, 7, 4, 6, 7, 3, 3, 6, 5, 8, 5]

    ```

- Using `map()` method:

    ```jsx

     let roots = ages.map(function(num) {
        return Math.floor(Math.sqrt(num));
     })

     console.log(roots);
     // [5, 3, 4, 4, 2, 7, 4, 6, 7, 3, 3, 6, 5, 8, 5]

    ```

- Using `map()` method with Array syntax (ES6):

    ```jsx

     let roots = ages.map(num => Math.floor(Math.sqrt(num)));
     console.log(roots);
     // [5, 3, 4, 4, 2, 7, 4, 6, 7, 3, 3, 6, 5, 8, 5]

    ```

### 4.  **Array.prototype.reduce()**

- The `reduce()` method is different from above three in the sense that it results in a **single value** from the array, while other **results in array**.
- **The reduce method executes a reducer function on each element of the array, resulting in a single output value.**
- Lets try to get sum of all the age's from the `ages` array:
- Using `for` Loop:

    ```jsx

     let ageSum = 0;
     for (let i = 0; i < ages.length; i++) {
         ageSum = ageSum + ages[i];
     }
     console.log(ageSum);
     // 460

    ```

- Using `reduce()` method:

    ```jsx

     const ageSum = ages.reduce(function(total, age) {
         return total + age;
     }, 0);
     // 460 

    ```

- Using `reduce()` method with Array syntax (ES6):

    ```jsx

     const ageSum = ages.reduce((total, age) => total + age, 0);
     // 460

    ```

### 5.  **Array.prototype.sort()**

- The `sort()` method sorts the elements of an array in place and returns the sorted array. The default sort order is ascending.
- By default, the `sort()` function sorts values as **strings**. This works well for strings ("Apple" comes before "Banana"). However, if numbers are sorted as strings, "37" is bigger than "200", because "3" is bigger than "2" ( initial character ). Because of this, the `sort()` method will produce incorrect result when sorting numbers. So,we have to fix this by providing a **compare function**:
- Lets try to sort our array of `ages`:
- Using `for` Loop:

    ```jsx

     for (let i = 1; i < ages.length; i++)
         for (let j = 0; j < i; j++)
             if (ages[i] < ages[j]) {
                 let temp = ages[i];
                 ages[i] = ages[j];
                 ages[j] = temp;
             }

     console.log(ages);
    // [5, 12, 13, 15, 16, 20, 21, 25, 32, 33, 44, 45, 54, 61, 64]

    ```

- Using `sort()` method:

    ```jsx

     const sortAges = ages.sort(function(a, b) {
    											return	 a - b 
    									});
     console.log(sortAges);
     // [5, 12, 13, 15, 16, 20, 21, 25, 32, 33, 44, 45, 54, 61, 64]

    ```

- Using `sort()` method with Array syntax (ES6):

    ```jsx

     const sortAges = ages.sort((a, b) => a - b);
     console.log(sortAges);
     // [5, 12, 13, 15, 16, 20, 21, 25, 32, 33, 44, 45, 54, 61, 64]

    ```

- Now, Let's sort array `studentDetails` based on startingYear:
- Using `sort()` method:

    ```jsx

     const sortedStudents = studentDetails.sort(function(s1, s2) {
         if (s1.startingYear > s2.startingYear) {
             return 1;
         } else {
             return -1;
         }
     });
     console.log(sortedStudents);

    ```

- Using `sort()` method with Array syntax (ES6):

    ```jsx

     const sortedStudents = studentDetails.sort((a, b) => (a.startingYear > b.startingYear ? 1 : -1));
     console.log(studentStudents);

    ```

So finally that's, all these are my key Learning from the **Chapter 5** of Book Eloquent Javascript. Also, Please do share your key learning from the Chapter 4 and what did you understood the most.

This is a **Bloging Challenge** from **#teamtanayejschallenge**

Here's a link to the Website: **[https://ejs-challenge.netlify.app/](https://ejs-challenge.netlify.app/)**

### **References:**

**[MDN Javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript)**

**[Javasript Info](https://javascript.info/)**

**[W3School Javascript](https://www.w3schools.com/js/default.asp)**

**Thank you very much for the patience. I’d love to hear your feedback about the post. Let me know what you think about this article, and javascript in general, through my [Twitter](https://twitter.com/NawarPrerana) and [LinkedIn](https://www.linkedin.com/in/prerana-nawar-4890b41ab/) handles. I would love to connect with you out there!**

**Peace!**