A Beginner's Guide to Mastering JavaScript Closures

SOURAV MOHANTYSOURAV MOHANTY
5 min read

Before going deep drive into closure in JavaScript I will recomend you to go through the concept of Higher Order Functions and Callbacks . I have already decribed it in details so you can acceess it on the blog named Mastering JavaScript: Understanding Callbacks and Higher-Order Functions . Let’s talk about closure in brief before doing that I will like to tell the need of it .

function iterate(array){
    let index = 0;
    return function foo(){
        let current = index;
        index ++;
        return array[current];
    }
}

let value = iterate([1,2,3]);
console.log(value()); // 1
console.log(value()); // 2
console.log(value()); // 3

So let’s explore this code and we will explore it line by line . Looks too overwelming ahh! Don’t worry I will make it simple for you that you can write this code like a for loop .

InDepth look on forEach()
If you ever closely looked at the forEach method then you must have think like that this method does track the index in a array and return the value of that perticular index. But if have not think about it I just mentioned here to make you think about it before using it second time blindly.

As I mentioned in my last blog, when JavaScript reads code, it processes it line by line. Since JavaScript is a single-threaded language, it manages memory alongside execution.

Line 1: We declare a function called iterate in global memory, and JavaScript saves its code in global memory for future use.

Line 2: We declare a variable named value and assign it the result of iterate([1,2,3]). But before doing that, we need to execute the iterate function to get the correct value. As we discussed earlier, whenever a function is called, a new execution context is created. So, we create a new execution context for the function iterate([1,2,3]).

## Iterate Execution context local memory
- array : [1,2,3]
- index : 0

## Global Execution context memory
- iterate - function ()
- value

As we know, after that, we return a function called foo. Earlier, we learned that a function is treated as a type of value in JavaScript. So, the code for this function is stored in the value variable in global memory.

## Iterate Execution context local memory
- array : [1,2,3]
- index : 0

## Global Execution context memory
- iterate - function ()
- value - function ()

Line 3: In the next line, we log the result of calling the function value(). As we know, whenever a function is called, a new execution context is created with its own local memory. But wait, we returned the function, and we know the execution context of the last iterate function call disappears after it returns. Yet, inside the value function call, we use the variables index and array. So, where do we find them? They're not in the value function call or in global memory.

Hmmm! 🤔🤔🤔🤔 That's strange, JavaScript, you're confusing. 😢😢

No, no! I think we missed something, and we need to discuss it.

When the iterate function call returned the function foo, it also returned a "backpack" of all the local variables used inside foo, like array and index. Whenever we call the value function, it first checks its own local memory, then its backpack, and finally the global memory. So, let's update the memory space for the value function.

## Backpack for function value
- array : [1,2,3]
- index : 0

## Local memory for function value
- current : 0

So, let's execute the value function step by step. In the first line, we declare a local variable named current and assign it the current value of index (which is 0). Then, we increment the index in the function's backpack by 1. Next, we return the value of the array (inside the backpack) at the current index (which is 0). As we discussed earlier, the result of the value function will be printed to the console, which is 1.

Okay, I got it. But how did it happen in the next line? 🤔🤔🤔

Let's go through it line by line, a bit faster this time. First, we call the value function again. Before executing, let's check the state of our backpack and our local memory.

## Backpack for function value
- array : [1,2,3]
- index : 1 // as we incremented the value on our last function call

## Local memory for function value
- current : 1

In the function value's local memory, we have current (which is 1). We then increment the index value from 1 to 2. Next, we return the value of the array at index 1 (which is 2), and the console will print 2. After this, I think you understand how it works internally. Remember, JavaScript doesn't go back to run foo when we call value because we have returned the code of foo and stored it inside value. It will always refer to value when we call it.

As we've discussed the term "backpack" many times, I mentioned the name my mentor used while teaching me. However, the actual name is Closed Over Variable Environment / Persistent Lexically Scoped Referenced Data / Closure.

Thank you for listining for this long and If you get something new today from my blog go and take the course on Frontend Masters which has the goldmine of courses and where you actually learn the fundamentals of the world of programming and you feel the spak how the things works under the hood in the world of JavaScript and It’s internals.

10
Subscribe to my newsletter

Read articles from SOURAV MOHANTY directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

SOURAV MOHANTY
SOURAV MOHANTY

Experience teaches the best way I wish I was taught