Using Callbacks and Closures in JavaScript
Tags: webdev, functional, javascript, beginners
Published: 2020-01-16 02:41:22

**Subscribe to my email list now at http://jauyeung.net/subscribe/**

**Follow me on Twitter at https://twitter.com/AuMayeung**

**Many more articles at https://medium.com/@hohanga**

Callbacks and closures are used frequently in JavaScript. Callbacks are functions that are passed into another function as an argument. Closures are functions that are nested in other functions, and it’s often used to avoid scope clash with other parts of a JavaScript program.

Callbacks
=========

Functions in JavaScript are objects. Like any other object, you can pass them in as a parameter. Therefore, in JavaScript we can pass in a function as an argument of another function. This is called a callback function. Functions can also be returned as the result of another function. Callback functions can be used for synchronous code and asynchronous code.

Passing in a function as a parameter of another function is different from calling a function. When we call a function, we add parentheses to the end of the function possibly with arguments inside. Functions that are called run immediately. When functions are passed in as an argument, they aren’t called immediately. They’re called when the function that you passed the callback function into calls it. For example, if we have:

```javascript
element.addEventListener('click', handleClick);
```

`handleClick` isn’t called immediately. It’s called when a click event is triggered by the user.

We can write our own function that takes a callback function as an argument by adding a parameter that takes a function. For example, we can write:

```javascript
const calculate = (x, y, callbackFn)=>{  
  return callbackFn(x, y);  
})
```

where `callbackFn` is a function parameter that runs inside the `calculate` function. If we want to use the `calculate` function to calculate something, then we write:

```javascript
const result = calculate(1, 2, (x, y)=>{  
  return x + y;  
});
```

`result` would is 3 above since we added the 2 numbers `x` and `y` in the callback function that we passed in. We can also pass in a named function as a callback function:

```javascript
const add = (x, y) => x + y;  
const result = calculate(1, 2, add);
```

We would get the same result. Also, if our function takes callback function, we can take in any other function as an argument:

```javascript
const add = (x, y) => x + y;  
const subtract = (x, y) => x - y;  
const multiply = (x, y) => x * y;  
const divide = (x, y) => x / y;  
const sum = calculate(1, 2, add); // 3  
const difference = calculate(1, 2, subtract); // -1  
const product = calculate(1, 2, multiply); // 2  
const quotient = calculate(1, 2, divide); // 0.5
```

As we can see, callback functions make our code more flexible as we can pass in whatever function we want as a callback function. Also, named functions are easier to read since we separated the callback function from the arguments. They can also be reused in other places easily.

However, we didn’t check that the `callbackFn` parameter is actually a function. This is going to be an issue if someone passes in something that isn’t a function. To check that it’s actually a function, we use the `typeof` operator, as follows:

```javascript
const calculate = (x, y, callbackFn)=>{  
  if (typeof callbackFn === 'function'){  
    return callbackFn(x, y);  
  }  
  return 0;  
})
```

To use callback functions in our web page, we put the following in `index.html` :

```html
<html>  
  <head>  
    <title>Calcuate</title>  
    <link href="styles.css" rel="stylesheet" type="text/css" />  
  </head>  
  <body>  
    <p>  
      The sum of 1 and 2 is <span id='sum'></span>  
    </p> <p>  
      The difference of 1 and 2 is <span id='difference'></span>  
    </p> <p>  
      The product of 1 and 2 is <span id='product'></span>  
    </p> <p>  
     The quotient of 1 and 2 is <span id='quotient'></span>  
    </p> <p>  
      The modulus of 1 and 2 is <span id='modulus'></span>  
    </p>  
    <script src="script.js"></script>  
  </body>  
</html>
```

Then in `script.js` we put:

```javascript
const calculate = (x, y, callbackFn) => {  
  return callbackFn(x, y);  
};

const add = (x, y) => {  
  return x + y;  
}

const subtract = (x, y) => {  
  return x - y;  
}

const multiply = (x, y) => {  
  return x * y;  
}

const divide = (x, y) => {  
  return x / y;  
}

const mod = (x, y) => {  
  return x % y;  
}

window.onload = ()=>{  
  const sum = calculate(1, 2, add);  
  const difference = calculate(1, 2, subtract);  
  const product = calculate(1, 2, multiply);  
  const quotient = calculate(1, 2, divide);  
  const modulus = calculate(1, 2, mod);  
  document.getElementById('sum').innerHTML = sum;  
  document.getElementById('difference').innerHTML = difference;  
  document.getElementById('product').innerHTML = product;  
  document.getElementById('quotient').innerHTML = quotient;  
  document.getElementById('modulus').innerHTML = modulus;  
}
```

Closures
========

A closure is a local variable or function that’s used by another function and the references to the function returned to the function. That is, we return a function in an outer function that references to the local variables of the outer function. This is possible if we have functions nested in another function and returned as a reference. In the inner function, we can use the variables of the outer function. Because of the scoping of local variables, inner functions can access the variables of the outer function. When we return the inner function in the outer function, the references to the local variables of the outer function are still referenced in the inner function.

For example, we can write the following code to return a function from an outer function:

```javascript
const hello = (name)=>{  
  const greeting = `Hello ${name}`;  
  const greet = () => alert(greeting);  
  return greet;  
}  
const helloJane = hello('Jane');  
helloJane();
```

`helloJane` is a function that’s returned by `hello`. Note that we still reference the `greeting` variable in the `helloJane` function. We get an alert box that says ‘Hello Jane’ in it. The local variable `greeting` is still accessible because we passed it into the `greet` function. Because the `greet` function has the `greeting` function passed in. However, the `name` parameter isn’t accessible to the outside anymore because we didn’t pass it to the `greet` function when we return it. As we can see closures allow us to have private data in our code while keeping access to some public data from the outside.

We can expand the example above to make functions to show any greeting. In `index.html` :

```html
<html>  
  <head>  
    <title>Calcuate</title>  
    <link href="styles.css" rel="stylesheet" type="text/css" />  
  </head>  
  <body>  
    <p id='hello'></p>  
    <p id='welcome'></p>  
    <p id='how-are-you'></p>  
    <p id='goodbye'></p>  
    <script src="script.js"></script>  
  </body>  
</html>
```

In `script.js` , we write:

```javascript
const createGreetingFn = (message)=>{  
  const greeting = message;  
  const greet = () => greeting;  
  return greet;  
}

window.onload = ()=>{  
  const hello = createGreetingFn('Hello');  
  const welcome = createGreetingFn('Welcome');  
  const howAreYou = createGreetingFn('How are you?');    
  const goodBye = createGreetingFn('Goodbye');  
  document.getElementById('hello').innerHTML = hello();  
  document.getElementById('welcome').innerHTML = welcome();  
  document.getElementById('how-are-you').innerHTML = howAreYou();  
  document.getElementById('goodbye').innerHTML = goodBye();  
}
```

As we can see, we can create multiple functions from the same function that does different things. A function that creates new functions is called a function factory. We created functions that different things from one function. This is another way to make our JavaScript more flexible and let us reuse our code. In the `window.onload` function, we called the functions that we created by the `createGreetingFn` that we called, which returns the results and then assigned the results to the `innerHTML` property of our elements.