DEV Community

Cover image for Understanding Closures in JavaScript
Avwerosuoghene Darhare-Igben
Avwerosuoghene Darhare-Igben

Posted on

Understanding Closures in JavaScript

Closures might seem puzzling at first, but they're actually a powerful tool in JavaScript. Think of them as hidden treasures that help make JavaScript work its magic. In this article, we'll uncover what closures are, how they work, and why they're important in making cool stuff with JavaScript.

What are Closures?

Closures, in easy words, empower functions to reach out and grab variables from the functions that hold them. Imagine it as if functions have a secret tunnel to their parent functions' treasure trove of variables. These tunnels are constructed when functions come to life, and they share a special connection. This link between inner and outer functions forms the groundwork for numerous advanced coding strategies and techniques in JavaScript.

Image description

In this example, the innerFunction is defined inside the outerFunction. When outerFunction is called and innerFunction is returned, it forms a closure. This closure allows innerFunction to access the treasure variable from its parent function's scope, even after outerFunction has completed execution. This demonstrates how closures create a connection between inner and outer functions, enabling access to outer variables.

Use Cases of Closures

Let's examine some of the use cases of closures:

- Data Encapsulation
Closure provides a means to encapsulate data within functions, allowing for controlled access to that data while keeping it hidden from the outside scope. This concept is crucial for maintaining data integrity, preventing unintended modifications, and creating more modular and organised code.

Image description

In this example, the createCounter function returns an object containing both the increment function and the getCount function. The count variable is encapsulated within the closure formed by the increment and getCount functions. The increment function can modify the count, and the getCount function can retrieve its value.

However, the count variable itself remains hidden from direct access from outside the closure. The getCount function serves as the only way to access the count value from the external scope.

- Functional Programming

Closures play a significant role in functional programming by enabling the creation of higher-order functions, which are functions that either take one or more functions as arguments or return a function as a result.

Image description

In this example, the multiplier function returns a closure that captures the factor argument. The returned function (double and triple) is a higher-order function that multiplies its input by the captured factor. This showcases the concept of closures in creating reusable higher-order functions.

- Event Handling

Closures are powerful tools for managing event handling in JavaScript. They allow you to attach functions to events while maintaining access to the surrounding scope, which is particularly useful for data encapsulation and avoiding global variables.

Image description

In this example, the setupClickHandler function attaches a click event listener to a button element. The anonymous function inside the addEventListener closure retains access to the count variable from its containing scope. This enables the function to increment and log the click count each time the button is clicked.

Managing Closures and Memory

While closures offer powerful capabilities, they can also lead to memory leaks if not managed carefully. When a closure references variables from its containing scope, those variables won't be garbage collected as long as the closure is in use. This can lead to a buildup of memory over time. To mitigate this, ensure that unnecessary closures are released by removing references when they are no longer needed.

Image description

By setting the closure to null when it's no longer needed, you allow the JavaScript engine to release the associated memory.

Conclusion

In the world of coding, closures are like tiny allies that enhance the adaptability and efficiency of your functions. However, remember to manage closures well. Don't leave them lying around when they're not needed. This keeps your codebase tidy and efficient. With closures in your toolkit, you'll soon be crafting awesome code effortlessly!

Top comments (9)

Collapse
 
vip3r011 profile image
vip3r011

Correct me if I'm wrong, but your last example is const , u cant reassign that to null

Collapse
 
avwerosuoghene profile image
Avwerosuoghene Darhare-Igben

Thanks for spotting that out. You are absolutely right, and that was an oversight from my end.
We can either define the expensiveClosure variable using the let keyword, or create a function inside our closure that releases resources when we no longer need them.

Collapse
 
manvendrask profile image
Manvendra Singh

That is why we use TypeScript, but here your editor should have caught it.

Thread Thread
 
avwerosuoghene profile image
Avwerosuoghene Darhare-Igben

Yeah, I used javascript for that particular snippet that's why.
More reason why typescript is essential.

Collapse
 
tallangroberg profile image
Tallan Groberg

Very well explained. Thanks for sharing.

Collapse
 
avwerosuoghene profile image
Avwerosuoghene Darhare-Igben

I'm pleased that the explanation was clear and beneficial to you.

Collapse
 
robinamirbahar profile image
Robina

Nice Work

Collapse
 
avwerosuoghene profile image
Avwerosuoghene Darhare-Igben

I'm glad you enjoyed the article.๐Ÿ™‚

Collapse
 
elayomohammed profile image
elayomohammed

Quite a good share, thanks ๐Ÿ˜Š