A Quick Introduction to Closures in JavaScript for New Developers
When you’re new to JavaScript, you may find some concepts challenging to wrap your head around. One such concept is ‘closure’. But worry not! Through this article, we will unravel this mysterious concept using a simple example. By the end, you’ll be able to harness the power of closures in your code with confidence.
What is a Closure?
A closure is a JavaScript function that has access to its own scope, the outer function’s scope, and the global scope. The closure has access to variables from three different scopes:
- Its own scope (variables defined between its curly brackets).
- Outer function’s scope (variables from the function it’s nested within).
- Global scope (variables defined outside of all functions).
Understanding closures can be a game-changer in how you structure and think about your code.
Let’s dive into the example:
const counter = () => {
let count = 0;
return () => {
console.log(++count);
}
}
let callCount = counter();
let flag = true;
setTimeout(() => flag = false);
while(flag){
callCount();
}
Now, let’s deconstruct this code and see closures at work.
The Counter Function
We first define a function counter
. Inside counter
, we declare a variable count
and set it to 0. Then, we return an anonymous function that, when called, increments count
and logs its value.
When we invoke counter()
and assign it to callCount
, it becomes the inner function - the anonymous function we returned from counter
. This inner function still has access to count
even after the counter
function has finished executing. This sustained access is the crux of JavaScript closures.
The While Loop
We then set flag
to true
and set a timeout to change flag
to false
. While flag
remains true
, the callCount
function gets continuously called within the while
loop. The callCount
function increments the count
and logs it to the console.
Here, callCount
has remembered the count
variable's state from its parent counter
function, even after the counter
function has run to completion.
Note: It’s important to know that the
while(flag){ callCount(); }
is an infinite loop because thesetTimeout
doesn't have time to change the flag tofalse
. It could cause the browser to freeze, and it's not recommended to use such an approach in a real application.
Conclusion
In JavaScript, closures are powerful and provide a lot of flexibility and control. Closures allow functions to keep track of variables from other scopes and use those variables even after those scopes have finished running. This “memory” makes closures instrumental in callback and asynchronous processes that are the backbone of JavaScript’s non-blocking nature.
As a new JavaScript developer, mastering closures would pave the way to understanding and implementing more complex JavaScript features like callbacks, promises, and async/await syntax.
Keep practicing, keep coding, and the once complex concepts will become second nature to you!