Closures in Javascript

29 / Feb / 2024 by deepesh.agrawal 0 comments

Understanding closures is like unlocking a hidden treasure within the world of JavaScript development. In this step-by-step guide, we’ll delve into the intricacies of closures, unraveling their mysteries and exploring the advantages they bring to your code.

What is a Closure ?

A closure in JavaScript is formed when a function is defined within another function, allowing the inner function to access the outer function’s variables. The inner function retains a reference to the outer function’s scope, even after the outer function has finished executing.

In simple terms, Function, along with its lexical scope, forms a closure

In this inner function is returned, as we can see that the outer function is executed, but if we go to execute the closureFn function, which actually contains the inner function will print X: 10, because it remembers its lexical scope, even after execution of its parent function.

In the screenshot, we can see a Closure object holds all the references of its outer variables.

Let’s see one more example with two inner functions:

  • The magic here is in the closure created by the inner function. Even though outer has finished executing, the inner function still retains access to the variables in the lexical scope of its outer function (outer), including x and a.
  • When closureFn is invoked, it executes the inner function, which logs the values of x and a. The value of x is 10 as expected, and the value of a is still accessible due to the closure, even though it is from the outermost function outest.

Use Cases of Closure

  1. Data Encapsulation: Closures allow for the creation of private variables. By encapsulating variables within a function’s scope, they are not directly accessible from outside, promoting information hiding and reducing the risk of unintentional modifications.

2. Function Currying

Closures play a key role in function currying, a technique used in functional programming where a function is transformed into a sequence of functions, each taking a single argument. This is achieved through the use of closures to capture and remember the previously provided arguments. Let’s delve into an example to illustrate the concept:

In this example, curryAdd is a currying function that takes an argument x and returns a closure that takes another argument y, which in turn returns another closure, taking the final argument z. When all three arguments are provided, the closures are executed, and the sum of the arguments is returned.

The magic here lies in the closures preserving the values of x and y even after their respective functions have completed execution. This enables the creation of partially applied functions, allowing for a more flexible and modular approach to function composition.

First Closure: curryAdd(1) // Returns a closure with x = 1

Second Closure: curryAdd(1)(2) // Returns a closure with x = 1 and y = 2

Third Closure: curryAdd(1)(2)(3) // Returns a closure with x = 1, y = 2, and z = 3, then calculates the sum (1 + 2 + 3)

Disadvantages of closures

While closures are powerful, but we should consider memory management. Since closures retain references to their outer scope, they may keep objects in memory longer than expected. This can lead to potential memory leaks if not managed appropriately.

Conclusion

Closures in JavaScript provide an elegant way to create encapsulated and reusable code. Understanding how closures work is essential for mastering JavaScript and leveraging its full potential, particularly in scenarios involving data encapsulation, data hiding, function currying, etc. As we dive deeper into JavaScript development, closures will become a valuable tool for writing clean, modular, and efficient code.

Check out our other blog posts for more insights.

FOUND THIS USEFUL? SHARE IT

Leave a Reply

Your email address will not be published. Required fields are marked *