Behind Higher-Order Functions with the Execution Context
Tags: javascript
Published: 2020-07-26 02:13:27

When I first learned the concept of Higher-order functions in JavaScript I used them and then moved on to the next item. This was a major mistake; the flexibility JS offers you in Higher-Order Functions allows for highly reusable code. So in this article, I am going to give a brief explanation of JavaScript's Execution context and then use this to show how Higher-Order Functions work behind the scenes
###Execution Context###
An execution context is described as the environment in which javascript code gets executed. The global space is a large execution context that is destroyed at the end of the program. To illustrate this I will cover the execution context of this function:
```
let multiplyArrayByTwo = (array) => {
    let newAry = []
    for(let i = 0; i < array.length; i++){
        newAry.push(array[i]*2)
    } 
    return newAry
}
let ary = [1,2,3,4,5,6]
let doubledAry = multiplyArrayByTwo(ary)
```
At the beginning of this program, multiplyArrayByTwo is set equal to the function definition that precedes it, and then ary is initialized and defined as an array of integers.

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

Then once we reach doubleAry something different happens. DoubleAry is equated to the result of multiplyByTwo with ary as its parameter. So with this, a new Execution context is created.

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

Then the function is pushed to the call stack, the array argument is set equal to ary, and newAry is defined and initialized as an empty array.

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

Once all of this is in order the function then executes the for loop, which does not get its own execution context. During this action, the items of array are doubled then pushed into newAry

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

Now that our function has doubled the array it then returns the newArray

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

This then defines doubledAry as the returned value, pops multiplyArrayByTwo off the call stack, and destroys the execution context along with anything inside of it.


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


So the above example is not bad but with Higher-Order Functions we can do much better

###Higher-Order Functions###

```
let modifyArray = (array, modification) => {
    let newAry = []
    for(let i = 0; i < array.length; i++){
        newAry.push(modification(array)
    }
    return newAry
}
let ary = [1,2,3,4,5,6]
let squareItem = num => num**2
let squaredArray = modifyArray(ary, squareItem)
```

Like we began in the previous example we set up the preliminary items by setting modifyArray equal to its function definition, setting array equal to an array of integers, and defining the function squareItem.

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

Then we reach squaredArray and on inspection of squaredArray's definition, there is a function call to modifyArray with ary and squareItem as arguments; thus creating a new EXECUTION CONTEXT. The function is then pushed onto the call stack and its variables are initialized.

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

Now, this is where the magic of Higher-Order Functions comes in. As most of you already could tell this function is way more useful than the previous. It can modify any array with any function you pass in as an argument. With that said let's examine this in another EXECUTION CONTEXT. Once we reach the for loop, modify is called on each item in the array and then pushed onto newAry. So modify is being pushed and popped off the call stack until the end of the for loop and returning the new value each time. 

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

Once the end of the for loop is reached the value in newAry is returned to squaredArray, modifyArray is pushed off the call stack, and only the global execution context remains.

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

Now if you really look at the function we examined above it should look familiar to many of you. It is just a basic map function. Higher-Order Functions can make your code much more flexible and can easily replace multiple functions with just a few tweaks to the code. This design was not my idea and I attribute it to the instructors at frontendmasters.com Thanks for reading I hope this helps.