
A closure is a stateful function that is returned by another function. It acts as a container to remember variables and parameters from its parent scope even if the parent function has finished executing. Consider this simple example.
functionsayHello(){constgreeting="Hello World";returnfunction(){// anonymous function/nameless functionconsole.log(greeting)}}consthello=sayHello();// hello holds the returned functionhello();// -> Hello World
Look! we have a function that returns a function! The returned function gets saved to a variable and invoked the line below.
Many ways to write the same code!
Now that you know what a closure is at a basic level, here are few ways to write the same code as above.
// originalfunctionsayHello(){constgreeting="Hello World";returnfunction(){// anonymous functionconsole.log(greeting)}}// #1functionsayHello(){constgreeting="Hello World";returnfunctionhello(){// named functionconsole.log(greeting)}}// #2functionsayHello(){constgreeting="Hello World";functionhello(){// named functionconsole.log(greeting)}returnhello;// return inner function on a different line}// #3functionsayHello(){constgreeting="Hello World";consthello=()=>{// arrow functionconsole.log(greeting)}returnhello;}
Pick a style you like the most and stick with it because every one of the above variations will still print the same result!
consthello=sayHello();hello();// -> Hello World
Benefits of closure and how it can be practical
Private Namespace
It's cool that the inner function remembers the environment that it was created in but what use does it have? A couple. First,it can keep your variables private. Here is the classic counter example.
functioncounter(){letcount=0;returnfunction(){count+=1;returncount;}}constincrement=counter();console.log(increment());// 1console.log(increment());// 2console.log(count)// Reference error: count is not defined
Trying to access the count variable gives us a reference error because it's not exposed to the global environment. Which helps us reduce bugs because our state is more strictly controlled by specific methods.
Reusable states
Because 'count' is privately scoped, we can create different instances of counter functions and their 'count' variables won't overlap!
functioncounter(){letcount=0;returnfunction(){count+=1;returncount;}}constincrementBananaCount=counter();constincrementAppleCount=counter();console.log(incrementBananaCount());// 1console.log(incrementBananaCount());// 2console.log(incrementAppleCount());// 1
Module design pattern
The module design pattern is a popular convention to architect your JavaScript apps. It utilizes IIFE(Immediately Invoked Function Expression) to return objects and exposes only the variables and methods that you want to make public.
letDog1=(function(){letname="Suzy";constgetName=()=>{returnname;}constchangeName=(newName)=>{name=newName;}return{getName:getName,changeName:changeName}}())console.log(name);// undefinedDog1.getName()// SuzyDog1.changeName("Pink")Dog1.getName()// Pink
As soon as this code runs, the function executes and returns an object which gets saved to Dog1. This pattern goes back to keeping our namespace private and only revealing what we want as public methods and variables via form of an object. The state is encapsulated!
The famous interview question
What's the outcome of running the following function?
for(vari=0;i<5;i++){setTimeout(function(){console.log(i)},1000)}
Why is this such a popular interview question? Because it tests your knowledge of function scope/block scope, closure, setTimeout and anonymous function! The answer prints out five 5s after 1 second.
55555
How? Well, setTimeout runs 5 times in the loop after 1 second. After the time delay, they execute functions inside, which simply logs out i. By the time 1 second has passed, the loop already finished and i became 5. Five 5s get printed out. Not what you were expecting? You probably want to see number 1 through 5 iteratively.
The solution
There are a few solutions, but let's focus on using closure!
for(vari=0;i<5;i++){setTimeout((function(index){returnfunction(){console.log(index);}}(i)),1000)}
We have our closure that is returned by an anonymous function to receive current 'i's as arguments and output them as 'index'. This in doing so captures the current variable i to each function. The result turns out to be
0 (...1000ms have passed)1 (...1000ms have passed)2 (...1000ms have passed)3 (...1000ms have passed)4 (...1000ms have passed)5 (loop exits)
Congratulations! 🎉🎉 Now you are more prepared for your next interview! 😉 Just remember that closure is a function that has access to the scope that encloses that function.
Top comments(9)

- LocationGermany
- EducationPhD
- WorkPostdoc at DICE, University of Leipzig
- Joined
The code in the final example is actually wrong:
for(vari=0;i<5;i++){setTimeout((function(index){console.log(index)})(i),1000)}
If you write like this, you might as well removesetTimeout
completely as it's not doing anything here (try setting timeout to 10s and see if it prints out the resultafter 10s).
What you are doing is this:
functionprintIndex(index){console.log(index)}for(vari=0;i<5;i++){setTimeout(printIndex(i),1000)}
This will just print out all index immediately andsetTimeout
will have no effect.
To fix this - you either need to return a function, or usingbind
when setting a timeout, e.g.:
functionprintIndex(index){return()=>console.log(index)}for(vari=0;i<5;i++){setTimeout(printIndex(i),1000)}

Hi Phillip,
Thank you for writing this great article on closures. The practical examples are easy to understand.
I wonder how, in the last example of the for loop, could you refactor the example so that each index prints out after the setTimeout value has elapsed
Like this:
0 (...1000ms have passed)
1 (...1000ms have passed)
2 (...1000ms have passed)
3 (...1000ms have passed)
4 (...1000ms have passed)
5 (loop exits)

I see that you made the edit!
But that is not actually what happens when you run the code.
The code you wrote prints 0-4 (all indexes) after 2000ms all at once.
I was curious how to make a loop that prints out each index, one at a time, according to the setTimeout value.
Maybe this isn't possible using a for loop.
I hope that makes sense!!

- Email
- LocationGujarat, India
- EducationBachelor of Computer Application
- Joined
They print all at once because all setTimeout starts at same time and for all setTimeout 1 second passes at same time. What you want can be achieved by passing timeout values to 1000, 2000, 3000....
Following code will give you that output:
for(var i=0; i<5; i++) { setTimeout((function(index) { return function() { console.log(index); } }(i)), 1000 * i)}

in the interview question about closure
why does it shows a different result when you use let in the for loops ?

- Email
- LocationAtlanta
- EducationMS in CS, Georgia Tech
- WorkEx-SWE @ Oracle | Vimeo
- Joined
let is a block scope. so the value of i gets captured. in case of var its a global scope/scope of where the function is called. so when the function actually executes, the var i value is the last standing value, which is not the case with let.
For further actions, you may consider blocking this person and/orreporting abuse