Closures in JavaScript Explained with Simple Examples | SUDBTECH

Closures in JavaScript Explained with Simple Examples | SUDBTECH

Sudip Mondal
0 Comments
60 mins, 1096 words

— with a little help from our cricketing heroes
 
Ever been to a cricket match? It starts off slow. Then boom. Sixes flying. Wickets falling. Unexpected twists.
JavaScript closures feel a lot like that. Quiet at first. Then, suddenly, powerful. Surprising. Useful.
 
Let me tell you a story.
 
 

Once Upon a Time in JavaScript

 
Virat and Rohit were coding together.
 

function battingPartner(name) {
  let message = `${name} is on strike`;

  return function() {
    console.log(message);
  };
}

const viratOnStrike = battingPartner("Virat Kohli");
viratOnStrike(); // "Virat Kohli is on strike"


Looks simple, right?
 
But something magical is happening.
 message lives inside battingPartner. Normally, it should disappear after the function finishes running.

But it didn’t.

Why?

Because of closure.
 
 

What is a Closure?

 
Closure is when a function “remembers” its outer variables.
Even after the outer function has finished executing.
 
Yeah. It sounds like memory magic. And it kinda is.
 
You see, in the example above—
The inner function (the one inside battingPartner) keeps the message alive.
Even though battingPartner is done and gone.
 
That’s closure.
 
Let’s bring in Mahi. Captain Cool himself.


A closure in JavaScript is created when a function is combined with the lexical scope in which it was declared.
This means that even after the outer function has finished running, the inner function still "remembers" and can access variables from its outer (enclosing) environment.

 
 

Dhoni Never Forgets

 

function finishMatch(runsNeeded) {
  let dhoniQuote = `We need ${runsNeeded} runs to win`;

  return function(finalOver) {
    console.log(`${dhoniQuote} in the last over: ${finalOver}`);
  };
}

const lastOverTension = finishMatch(15);
lastOverTension("Dhoni hits 2 sixes and a four");


Output?
 

We need 15 runs to win in the last over: Dhoni hits 2 sixes and a four


Dhoni didn't forget. Neither did the closure.
 The variable dhoniQuote lived on. Wrapped inside the returned function.
 
JavaScript tucked it safely in a corner of memory.
 
 

Real-Life Use? Yes, Bro!

 
Closures aren't just party tricks. They’re everywhere.
 
Think of a counter. Every time a batter scores, we want to update his runs.
 

function createScorer(playerName) {
  let score = 0;

  return function(runs) {
    score += runs;
    console.log(`${playerName} has scored ${score} runs`);
  };
}

const rohitScorer = createScorer("Rohit Sharma");

rohitScorer(4); // Rohit Sharma has scored 4 runs
rohitScorer(6); // Rohit Sharma has scored 10 runs


That score? It sticks. Doesn’t reset. Even though createScorer is long gone.
 
Rohit keeps batting.
 The closure keeps the score.

But Hold on.. Is That Safe?

 
Closures sound fantastic.
 However, occasionally... they deceive you.
 
particularly within loops.
 
Let me share a story with you.
 
 
Virat wrote a quick piece of code.
 He wanted to loop through 3 balls and log each one.
 
Simple idea.
 
So he wrote:
 

function wrongLoop() {
  for (var i = 1; i <= 3; i++) {
    setTimeout(function() {
      console.log("Ball", i);
    }, 1000);
  }
}

wrongLoop();


He expected to see:
 

Ball 1  
Ball 2  
Ball 3  


But after a second... boom:
 

Ball 4  
Ball 4  
Ball 4  


What? Ball 4?
There was no Ball 4. He only looped till 3.
 
Something was broken.
 
 
He scratched his head. Called Rohit. Rohit chuckled.
 

"It’s the closure, bro."


See, here’s what happened—
 
The function inside setTimeout didn’t run right away.
It ran after the loop was over. After one second.

By then, the loop had already finished.
And i had already become 4.

All the setTimeout callbacks were sharing the same i.
Because var doesn’t create a new scope for each iteration.
 
So, every one of them looked at i after the loop finished.
And saw... 4.
 
Not magic. Just scope.
 
 
Then Shubman came in.
 
Fresh mind. Young blood.
 
He said:
 

“Use let, bhai. Trust me.”


So they tried this:
 

function correctLoop() {
  for (let i = 1; i <= 3; i++) {
    setTimeout(function() {
      console.log("Ball", i);
    }, 1000);
  }
}

correctLoop();


And this time?
 
Perfect.
 

Ball 1  
Ball 2  
Ball 3  


No Ball 4. No confusion.
 
 

Why It Worked

 
let is block-scoped.
 
Which means each time the loop runs, it creates a new i.
A fresh copy. Just for that iteration.

So when the closure forms inside setTimeout,
it closes over the correct value of i.

Each callback holds its own memory.
Its own number.

No overlap. No overwrite. No chaos.

Closures do their job.
If you give them the right scope.

A Little Caution Goes Far

 
It’s a small thing. var vs let.
 
But in JavaScript, that small thing? It changes the whole story.
 
Closures are powerful. But they follow the rules of their environment.
 
And if you break the scope, they’ll bring ghosts from the future.
 Like Ball 4.
 
So. Be careful.
 
Let your variables breathe in their own space.
 
And JavaScript?
 It’ll keep your score right. Every time.

Wait—So What’s Scope Again?

 
Closures and scope… they’re like opening pair in cricket.
 Always together.
 
If you don’t get scope, closures will confuse you. Every time.

Scope is basically—where your variables live.
Where they’re born. And where they can be used.
 
Let me put it this way—
 

function stadium() {
  let crowd = "Cheering";

  function commentator() {
    console.log(crowd); // Works fine
  }

  commentator();
}

stadium();


Here, commentator() can access crowd.
 Because it’s inside the same scope. It’s a child.
 
But go outside the function and try this:
 

console.log(crowd); // Error: crowd is not defined


Nope. Crowd doesn’t exist out here.
 Because its scope is limited. Bound to the stadium function.
 
Closure relies on this rule.
 
It holds on to the variables from the scope it was born in.
Even after the parent function is done.


If all this is a little hazy, don’t worry.

I wrote a full beginner-friendly guide on Scope and Hoisting just for you.

👉 Read it here: Scope and Hoisting Explained Simply in JavaScript — by SBT
 
That blog will give you solid ground.
So closures? They’ll start making more sense.
 
Trust me. You’ll feel like you're reading the pitch better.

Final Over Thoughts

 
Closures aren’t hard. They’re... sneaky.
 They hang around in the background. Holding data. Waiting for the right time.
 
Sometimes it’s Virat on strike. Sometimes it’s Mahi in the last over.
 What’s constant? The closure. Keeping memories alive.
 
So next time someone says, "Closures are tricky," just smile.
 
And whisper—
 

"Dhoni doesn’t forget. Neither does JavaScript."


0 Comments