AN EASY GUIDE TO UNDERSTANDING CLOSURES IN JAVASCRIPT
Tags: javascript, tutorial, beginners, webdev
Published: 2020-05-01 14:56:43

---
title: AN EASY GUIDE TO UNDERSTANDING CLOSURES IN JAVASCRIPT
published: true
description: Completely explaining the concept of closures in Javascript in the most simple way
series: functional programming in JavaScript
tags: Javascript, tutorial, beginners, webdev
cover_image: https://res.cloudinary.com/drquzbncy/image/upload/v1588087604/DEV.TO/js_animation_iy8udq.gif
---

## Table of Contents
  1. [An Introduction To Closure](#chp-1)
  2. [The Fundamental Tenets](#chp-2)
  3. [Scope And Scope Chain](#chp-3)
  4. [A Second Look At Closure](#chp-4)
  5. [Closing Thoughts](#chp-5)

#### 1. An Introduction To Closure <a name="chp-1"></a>
Closures are an extremely powerful feature of the JavaScript programming language.

> :bulb: *A closure is a combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time.* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures)

The superb definition above utterly explains a closure. It is actually a feature of the JavaScript language, it is not something we code; it just happens due to the way the JavaScript language works. As a result of this, a function is able to access the variables of its parent (outer) function even after that function has returned.

Let's throw more light on the above definitions with an example below:
*Kindly run the code below and consider its result.*
{% runkit %}
function getBio(shortDevBio) {
    return function(devName) {
        console.log("Hi, my name is " + devName + " " + shortDevBio);
   }
}

const talkAboutDev = getBio("I am a developer, writer and instructor")
talkAboutDev("Lawrence Eagles") 
{% endrunkit %}

Our small contrived example above features a function *getBio* that takes a succinct developer bio and returns another function (an anonymous function) that takes a developer name. This inner function then tells us about the developer by logging his name and his bio to the console. 
One thing to note is that the *getBio* function does not return a function call but rather it returns an anonymous function. This means that when the *getBio* function is called it returns the code below:
```js
function(name) {
        console.log("Hi, my name is " + name + " " + shortDevBio);
   }
```
And because this is an anonymous function we assigned it to the variable *talkAboutDev*. Then we called this anonymous function through the *talkAboutDev* variable which now holds a reference to it in memory. 
I have already explained why this is possible in my previous article in the ***functional programming in JavaScript series***.
If this is not very clear for you, I would kindly suggest that you refer to my article on anonymous and first-class functions in JavaScript for a quick brush-up. You can access it below:
{% post https://dev.to/lawrence_eagles/understanding-first-class-functions-and-anonymous-functions-in-javascript-b2d %}

So when we call the *talKAboutDev* function, it tells us about the developer whose bio was passed to the *getBio* function.
*This is puzzling:exclamation:*

> How did the *talkAboutDev* function get the bio of the developer since the getBio function has already returned before it was called :question:

You can have a second look at the codes as you digest this question:
```js
function getBio(shortDevBio) {
    return function(devName) {
        console.log("Hi, my name is " + devName + " " + shortDevBio);
   }
}

const talkAboutDev = getBio("I am a developer, writer and instructor")
talkAboutDev("Lawrence Eagles") // returns "Hi, my name is Lawrence Eagles I am a developer, writer, and instructor"

// But how did it get the developer bio?
```
> :bulb: *This is possible because of closure. The inner function talkAboutDev still has access to the (free) variables of the outer (getBio) function even after it has returned.*

The above answer may not really be satisfying especially if you do not have good knowledge of closure in JavaScript before now. We will be taking a deep look at this notorious, often difficult to understand, and extremely powerful feature in the JavaScript programming language in the remaining sections below.

> :sparkles: *It is very important to have a good understanding of closure in JavaScript especially if you want to level-up your skill of the language.* 

In other to fully understand closure in JavaScript, we need a solid understanding of some key concepts, which are its fundamental tenets. 
We will be looking at these in the next section.

#### 2. The Fundamental Tenets <a name="chp-2"></a>
Section 1 gives us an overview of closure. Although we saw it in action there are still some unanswered questions. In other, for us to get a thorough understanding of it, we need to learn about the key concepts that come into play when closures are created in JavaScript. 
Let's deal with them below.

##### 1. The Execution Context.
> :bulb: *Every code in JavaScript runs inside a wrapper around it called the execution context*

When a JavaScript program runs, a base (global) execution context is created and it wraps around all the codes.
*Consider the image below:*

![Alt Execution context](https://res.cloudinary.com/drquzbncy/image/upload/v1588110041/DEV.TO/global_execution_context_1_whgiqk.png)

From our image, we can see that the global execution context is made up of the global object, the ***this*** variable, the variable environment, and the outer environment.

In other to get a good understanding of closure and even the JavaScript language we need to learn about all these and how they interact when our program runs.

##### The Global Object
This is the ***window*** object. It represents your browser's current tab. If you open another tab, you would get a separate global object because that would create a separate execution context. In a ***Node.js*** environment, however, the global object is not the window object.

> :bulb: *In the browser the global object is the* ***window*** *object but in* ***Node.js*** *the global object is called the* ***global*** *object* 

Kindly run and consider the result of the code below:
{% runkit %}
console.log(this)
{% endrunkit %}

> :bulb: *When the JavaScript engine runs your code for the first time, the global execution context is created. This would still be created even if the* ***.js*** *file is empty*

The runkit program above is an empty *.js* file. Notice that the global execution context was still created hence we get the global object in the console. *Note runkit is a node.js environment so the global object is called global*
![Alt the global object in console](https://res.cloudinary.com/drquzbncy/image/upload/v1588111063/DEV.TO/Screenshot_2020-04-28_at_22.56.19_slzpsa.png)

##### The ***this*** variable or keyword
This is a special JavaScript object. I have dealt with it in more detail in one of my articles in the OOP (Object Oriented Programming) in JavaScript series. kindly read more about it below.
{% post https://dev.to/lawrence_eagles/understanding-prototypal-inheritance-in-javascript-4f31 %}
All we would say here is that at the global level the ***this*** variable is equal to the global object. *It points to it.*

##### The Variable Environment
This refers to where the variable lives in memory and how they relate to each other. Each execution context has its own variable environment. For the global execution context, the variable environment is the global object.

##### The outer Environment
When we execute code inside a function, the outer environment is the code outside that function but at the global level, the outer environment is *null* because there is nothing outside it. *We are at the outermost level*.

Let's elaborate on these by considering some examples.

*Kindly examine the code below. 
In what order do you expect to see the three* ***console.log()*** *results:question:* 

> :bulb: *A good tip to note as you go through this exercise, is that a new execution context is created whenever a function is called, and this is added to the top of the execution stack. Also whenever a function returns its execution context is removed from the execution stack*

```js
function father() {
    child();
    let lastName = "Eagles"
    console.log(lastName)
}

function child() {
   let firstname = "Lawrence";
   console.log(firstname)
}

father();
var fullName = "Lawrence Eagles";
console.log(fullName);
```

Before we run the example above on runkit, let's take a deeper look at how the JavaScript engine would execute this code.

* At first the global execution context is created and all these functions and variables are added to a place in memory (in the global execution context, this is the global variable).

> There are two phases in the creation of the execution context viz the creation phase and the execution phase. I have covered this in an old article you can access it below.

{% post https://dev.to/lawrence_eagles/demystifying-hoisting-in-javascript-4kcj %}

* During the execution phase of the global execution context creation, the *father()* function is called and this creates a new execution context that is placed on top of the execution stack. The codes within this execution context (literally the codes in this function's code-block) will then be executed. 

* The *child()* is called as the codes within the *father* function's code block are executed and a new execution context is created and placed on top of the execution stack. 
The codes within the *child* function's execution context (the execution context on top of the execution stack) will now be executed. 

> :bulb: *As a rule if a function is called within a function a new (the inner function's) execution context is created and put on top of the execution stack and until the inner function returns and its execution context is removed from the execution stack the codes of the parent function will not be executed.*

* During the execution of the codes in the *child* function's execution context, the *string* "Lawrence" is assigned to the *firstName* variable and that is logged to the console.

* The *child* function returns and its execution context is popped off the execution stack (it is removed). The parent function's execution context now sits on top of the execution stack; thus the execution of its code will now continue.

* Next, the *string* "Eagles" is assigned to the variable *lastName* and that is logged to the console. This marks the end of the execution of the *parent* function; consequently, its execution context is popped off the execution stack and we have the global execution context left.

* Only now will the remaining codes in the global execution context be executed. The *string* "Lawrence Eagles" is now assigned to the variable *fullName* and that would be logged to the console.

From the explanation above we expect to get this result:
```js
// "Lawrence"
// "Eagles"
// "Lawrence Eagles"
```

Kindly run and examine the code below.

{% runkit %}
function father() {
    child();
    let lastName = "Eagles"
    console.log(lastName)
}

function child() {
   let firstname = "Lawrence";
   console.log(firstname)
}

father();
var fullName = "Lawrence Eagles";
console.log(fullName);
{% endrunkit %}

#### 3. Scope And Scope Chain <a name="chp-3"></a>
As we look at the scope and scope chain in this section, we will elaborate on the *variable environment* and the *outer environment* with code examples

*Kindly consider the codes below.*

> :bulb: *A good tip to note is that when the JavaScript engine does not see a variable in the* ***variable environment*** *of an execution context, it would go out to its* ***outer environment*** *to look for it.*

```js
function logDevName() {
   console.log(devName)
}

function logDevName2() {
    var devName = "Lawrence Eagles"
    console.log(devName)
    logDevName()
}

var devName = "Brendan Eich"
console.log(devName)
logDevName2()
```
*What do you think would be the values of the devName variable at each* ***console.log()***:question:

To answer this question let's go through the way the JavaScript engine would execute this code.

* First the global execution is created and all these functions and variables are added to a place in memory (in the global execution context, this is the global variable).

* During the execution phase of the global execution context creation, the *string* "Brendan Eich" is assigned to the variable *devName* and that is logged to the console.
* Then the *logDevName2* function is called and a new execution context is created and put on top of the execution stack.
* In the execution of the *logDevName2* function, the *string* "Lawrence Eagles" is assigned to the variable *devName* and that is logged to the console; thus, *devName* in this execution context is "Lawrence Eagles".
* Next, the *logDevName* function is called and a new execution context is created and put on top of the execution stack.
* During the execution of this function, the variable *devName* is logged to the console. But it is not in this local ***Scope*** because it is not in the variable environment of this functions' execution context (**it is not declared within this function**).

> :bulb: *A scope is a place where a variable can be found.* 

* So the JavaScript engine would go out to its ***outer environment*** to look for this variable; in this case, the ***outer environment*** is the global execution context. This is so because of the ***lexical environment*** of the *logDevName* function.

> :bulb: *The lexical environment refers to where something is written physically in your code. The JavaScript engine uses this to determine how things would sit in memory and how they would connect to each other. In our example, both the logDevName and the logDevName2 functions are sitting in the global execution context; therefore, it is the outer environment of both functions, even though the logDevName function is called inside the logDevName2 function*.

* The *devName* variable is found in the variable environment of the global execution context and there it is "Brendan Eich" hence the *string* "Brendan Eich" is logged to the console.
You can have a second look at the code below, and hopefully, you should now have a better understanding as you run it in runkit to see the result. 

{% runkit %}
function logDevName() {
   console.log(devName)
}

function logDevName2() {
    var devName = "Lawrence Eagles"
    console.log(devName)
    logDevName()
}

var devName = "Brendan Eich"
console.log(devName)
logDevName2()
{% endrunkit %}

> :bulb: *The JavaScript engine goes out of a function's execution context to its outer environment using the reference to that outer environment and continues to go up until it reaches the global execution context. This connection of links or references to different outer environments is called the scope chain* 

#### 4. A Second Look At Closure <a name="chp-4"></a>
Since we now have an understanding of all the fundamental tenets required to grasp the concept of closure, let's revisit the first example and answer our long-standing question.

> :sparkles: *Kindly note this when a function returns and its execution context is removed from the execution stack, its inner function will still have access to the variables in its variable environment as the JavaScript engine performs its search up the scope chain*

{% runkit %}
function getBio(shortDevBio) {
    return function(devName) {
        console.log("Hi, my name is " + devName + " " + shortDevBio);
   }
}

const talkAboutDev = getBio("I am a developer, writer and instructor")
talkAboutDev("Lawrence Eagles") 
{% endrunkit %}

The inner function is able to get the value of the *shortDevBio* variable even after the *getBio* function has returned and its execution context has been removed from the execution stack because its inner function still holds a reference to its variable environment. Thus, the JavaScript engine is able to find the location of the (free) variables (e.g *shortDevBio*) in the variable environment of the *getBio* function as it continues its search up the scope chain.

Therefore, we can say that the execution context of the inner function encloses its outer variables. We can also say that it encloses all the variables that it is supposed to have access to. This phenomenon is referred to as ***closure.***

It makes possible some very powerful javascript design patterns used in some of the most popular JavaScript frameworks and libraries. 

The code above can be re-written like this using an alternate syntax.
*Kindly examine the code below:*

```js
function getBio(shortDevBio) {
    return function(devName) {
        console.log("Hi, my name is " + devName + " " + shortDevBio);
   }
}

// uses an alternate syntax to run both functions in one line.
const developerBio = getBio("I am a developer, writer and instructor.")("Lawrence Eagles")
console.log(developerBio)
```
*What do you think the* ***console.log()*** *would output:question:*

:bulb: *The alternate syntax uses two parentheses. The first () simply calls the outer (getBio) function and since that returns another function the second () calls the inner function, hence we get the same result*

You can run the code in runkit below:

{% runkit %}
function getBio(shortDevBio) {
    return function(devName) {
        console.log("Hi, my name is " + devName + " " + shortDevBio);
   }
}

// uses an alternate syntax to run both functions in one line.
const developerBio = getBio("I am a developer, writer and instructor.")("Lawrence Eagles") 
{% endrunkit %}

We see this pattern in action when we work with React and Redux using the [*React-Redux*](https://react-redux.js.org/) library.  

> :sparkles: *React-Redux is a library that connects React and Redux together. It poses itself as the official React bindings for Redux and it is maintained by the Redux team.*

Below is an extract from an example in their [official doc](https://react-redux.js.org/api/connect).

```js
export default connect(
  null,
  mapDispatchToProps
)(TodoApp)
```

The details of what is going on here are out of the scope of this article but I just want to point out the way the *connect* function is called with two parentheses. The first takes *null* and *mapDispatchToProps* while the second takes the *TodoApp* component as its argument the result is then exported. 
This pattern is made possible because of ***closure*** in JavaScript.

#### 5. Closing Thoughts <a name="chp-5"></a>
It has really been a long article and if you got here you are appreciated. 
I do hope that at this point, you can see the benefits of our long discussion and at least got a thing or two from this article. If so I would be looking forward to hearing your opinions, comments, questions, or requests (in case anything is not clear) at the comments section below.