What is a Closure? Why Do I Need to Use Closure?

What is a Closure? Why Do I Need to Use Closure?

Daily short news for you
  • These past few days, I've been redesigning the interface for the note-taking app OpenNotas. It's quite strange to think about why I chose DaisyUI back then 😩

    » Read more
  • Previously, there was a mention of openai/codex - a type of agent that runs conveniently in the Terminal from OpenAI, especially since it is open source and they have now added support for other providers instead of just using the chatgpt model as before.

    Recently, Anthropic also introduced Claude Code which is quite similar to Codex, except it is not open source and you are required to use their API. Since I don't have money to experiment, I've only heard that people in the programming community praise it a lot, and it might even be better than Cursor. On the flip side, there's the risk of burning a hole in your wallet at any moment 😨

    » Read more
  • For a long time, I have been thinking about how to increase brand presence, as well as users for the blog. After much contemplation, it seems the only way is to share on social media or hope they seek it out, until...

    Wearing this shirt means no more worries about traffic jams, the more crowded it gets, the more fun it is because hundreds of eyes are watching 🤓

    (It really works, you know 🤭)

    » Read more

Issue

Closure is an important concept in programming that allows you to implement functions more easily.

Closure is also quite popular in the world of JavaScript programming. Some people may have never heard of closure but may have inadvertently used it, while others may have heard of it but not fully understood it due to its abstract nature. So let's continue reading this article to explore more.

Lexical Scope

First of all, let me introduce a little bit about Lexical scope: in a group of nested functions, the inner functions have access to variables and other resources within the scope of their parent function. Lexical scope is sometimes also called Static scope.
For example:

function foo() {
  const a = 1;
  function bar() {
    console.log(a);
  }

  bar(); // 1
}

Even though the variable a is not inside the bar function, bar is inside foo so it can still access the variable a.

Closure

Similarly, closure follows the principle of Lexical scope. It can access variables of other functions outside of its own scope, as well as global variables. However, one important thing to note is that closures can still retain the state of the variables inside them. In other words, every time you return a function or assign a function to a variable, it carries the values of all the dependent variables.

For example:

function add(x) {
    return function addTo(y) {
        return x + y;
    }
}
const addFive = add(5);
const addToTen = addFive(10);
console.log(addToTen); // 15

In the above example, the add function takes a parameter x and then returns a function that takes a parameter y and returns the sum of x and y.

First, when we call add(5), we might think that the variables x and y in add will no longer exist. However, after calling addFive(10), we still get the result as 15. This means that the state of the add function is still preserved even after the function has been executed. If it wasn't preserved, addFive(10) wouldn't know that the value of the previous call to x was 5.

From this, we understand that when add returns the addTo function, addTo is enclosed in a context that includes both x and y at that particular moment.

So, now that we understand the theory behind closures, what are their benefits?
First, let's revisit a classic example:

for(var i = 0; i < 5; i++) {
    setTimeout(() => {
        console.log(i);
    }, 0);
}

We expect the result to be 0 1 2 3 4, but unfortunately, the actual result is 5 5 5 5 5. This is because setTimeout is only executed after the loop has finished iterating, and at that point, the reference value of the variable i in the console.log functions is already 5.

To solve this problem, we can replace var with let, or we can use closures to encapsulate the setTimeout and create a separate context for the function at that moment:

for(var i = 0; i < 5; i++) {
    (function(j) {
        setTimeout(() => {
            console.log(j);
        }, 0);
    })(i);
}

In addition, closures are also used to create scopes for object properties.

Consider the following example:

class Person {
  constructor(name) {
    this.name = name;
  }

  getName() {
    return this.name;
  }

  setName(name) {
    this.name = name;
  }
}

The getName and setName functions are added to prevent direct access to name. However, because JavaScript classes do not support access modifiers, name can still be easily modified as usual.

const p = new Person();
p.setName('estacks');
p.getName(); // estacks

p.name = 'edited';
p.name; // edited;

To prevent this, let's try using a closure:

function Person() {
  let _name;
  const getName = () => {
    return _name;
  }

  const setName = (name) => {
    _name = name;
  }

  return {
    getName,  
    setName,  
  }
}

const p = Person();
p.setName('estacks');
p.getName(); // estacks

p._name; // undefined

The Person function returns two closure functions that have access to _name.

As you can see, direct access to the _name variable is not possible. Any operations involving _name must be done through the setName and getName functions.

Another application of closures is with curry functions. For those who have not read or are not familiar with curry functions, you can read my article What is a Curry Function? A Delicious "Curry" Dish and How to Enjoy It?. Closures make it easier than ever to create a curry function, and it has a lot of practical applications as well.

Conclusion

Closure is not just a concept specific to JavaScript; many other languages also support it. Closure is a function that follows the principles of Lexical scope and has the ability to retain the state of the variables it depends on. Closure has many important applications, such as creating access modifiers, curry functions, and more. Closure is also an important knowledge in interviews to assess your understanding of the JavaScript language.

References:

Premium
Hello

Me & the desire to "play with words"

Have you tried writing? And then failed or not satisfied? At 2coffee.dev we have had a hard time with writing. Don't be discouraged, because now we have a way to help you. Click to become a member now!

Have you tried writing? And then failed or not satisfied? At 2coffee.dev we have had a hard time with writing. Don't be discouraged, because now we have a way to help you. Click to become a member now!

View all

Subscribe to receive new article notifications

or
* The summary newsletter is sent every 1-2 weeks, cancel anytime.

Comments (1)

Leave a comment...
Avatar
Đông Nguyễn Văn2 years ago

Bài viết hay, em cảm ơn tác giả ạ.Nhưng ở đoạn kết quả của nó lại là 4 4 4 4 4.Em nghĩ là 5 5 5 5 5 đúng không ạ?

Reply
Avatar
Xuân Hoài Tống2 years ago

@gif [Q2aN4iiaibCus] Xin lỗi, đúng là mình có sai sót và đã sửa lại bài viết. Cảm ơn bạn nhé.