Why nested functions in JavaScript
Tags: javascript, node, typescript, webdev
Published: 2020-05-25 15:48:26


Often many people confused about nested function in JavaScript, why the nested function is useful, and what is the use case for nested function? There are so many places we might encounter such nested functions in our code or blog post or articles.

In this article, I would like to talk about the basics of why nested functions are useful in many ways.

I'll start asking some basic questions along with some constraints that way it may help to think differently to solve the problem. Let's assume that we have employee array like below

```javascript
const employee = [
  { id: 1, name: "Raja", age: 28, status: "active" },
  { id: 2, name: "Andy", age: 32, status: "Inactive" },
  { id: 3, name: "Kumar", age: 45, status: "active" },
  { id: 4, name: "Charles", age: 35, status: "Inactive" },
];

```

## Use case 1 # 
  How do you sort an array by property (age, status, etc)?

**Constraint**: Do not pass an array as a reference to any other functions and function should be more reusable.

Typically, with our prior programming knowledge, we do sorting using *Array.prototype.sort* function like below

```javascript
function sortBy(array, propName) {
  return array.sort(function (a, b) {
    if (a[propName] > b[propName]) {
      return 1;
    } else if (a[propName] < b[propName]) {
      return -1;
    } else {
      return 0;
    }
  });
}

console.log(sortBy(employee, "age"));
console.log(sortBy(employee, "status"));
```

The above code does the job nicely but just take a look into our first constraint for the first use case. so it's clearly saying that's not the way to do. Note that, we are passing array reference to the function :(

In general, this is how we do sorting in JavaScript

```javascript
// How do to pass another arguments to tell sort based on which property of an object ???????
Array.prototype.sort(function(a, b)) 
```

As we know *Array.prototype.sort* interface only accepts 2 arguments, So  How do we pass *propName* as another argument? now we clearly understand that *sort* method accepts only 2 parameters we can't pass any extra argument to the function anymore.  

Okay then how do we solve the problem?.

Hint: can we make our custom argument accessible inside sort callback function without adding an extra argument to *Array.prototype.sort*?

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

This is a perfect moment to use function inside a function (often called higher-order function) so that we could return a function which accepts only 2 arguments as per sort interface requirement, the high order function can accept n of arguments so that we can access our custom argument inside the sort callback function.

Here is the second version of sortBy function

```javascript

function sortBy(propName) {
  return function (a, b) { // obeying sort interface function signature
    if (a[propName] > b[propName]) { // propName accessible from highorder function
      return 1;
    } else if (a[propName] < b[propName]) {
      return -1;
    } else {
      return 0;
    }
  };
}

console.log(employee.sort(sortBy("age")));
console.log(employee.sort(sortBy("status")));
```

I would like to discuss one more use case for higher-order functions with filter use case

### Use case 2:

  How do you filter an array with an inactive employee?

**Constraint**: Assume that we have function for filter out all active employee(isActiveEmployee) function already exists, Use the same function to get all inactive employee without code duplication.

```javascript
function isActiveEmployee(employee) {
    return employee.status == 'active';
}

const activeEmployee = employee.filter(isActiveEmployee);
// const inactiveEmployee = employee.filter(??????);
```

Okay we might come up with below solution easy without thinking anything

```javascript
function isInactiveEmployee(employee) {
     return employee.status !== 'active';
}

//(or)

 function isInactiveEmployee(employee) {
     return employee.status === 'inactive';
}
```


Just gentle reminder of use case 2's **constraint**, it said, we should n't duplicate the code, so can we do it a better way?

So think of we have already code which finds all active employees, so it just to invert the result of **isActiveEmployee** function we will get the all inactive employee even without write a brand new function for filter out inactive employee.

Method looks like

```javascript
 function negate(item){
     return !isActiveEmployee(item)
 }
```

 But we can do even better, we may think of *negate* as utility functions so it can be written like below

```javascript
  function negate(predicate){
      return function() {
          return !predicate.apply(this, arguments)
      }
  }
```
Here is solution for filtered out all inactive employee

```javascript
const inactiveEmployee = employee.filter(negate(isActiveEmployee));

console.log({inactiveEmployee});

```

Hope now you can see some of the benefits of high order function such as

1. Cleaner abstraction 
2. working with composable functions and many more

### Further Readings:

https://eloquentjavascript.net/05_higher_order.html
https://javascript.info/currying-partials