DEV Community

Prasanth Bupd
Prasanth Bupd

Posted on

Understanding Closures

What is Closures?

Closures are a foundational concept in JavaScript that allows inner functions to access variables from their parent function's scope, even after the parent function has finished executing. This makes closures a powerful tool for data privacy, callbacks, and functional programming.

Why do I need it?

A closure is created when an inner function captures references to variables from an outer function's scope. For example:

function outer() {
    let outerVar = 10;

    function inner() {
        console.log(outerVar);
    }

    return inner; // We're returning the inner function itself
}

// Execution:

const closureFunction = outer(); // `inner` captures `outerVar`
closureFunction(); // Output: 10
Enter fullscreen mode Exit fullscreen mode

In this example, inner is a closure because it references outerVar. Even after outer completes execution, inner maintains access to outerVar.

It is because, When a function is defined within another function and it captures (references) variables from the outer function, a closure is created. The inner function holds a reference to these variables, even if the outer function has completed execution and its variables should normally be garbage-collected. But that does not happen in the case of closures.

Access Beyond Execution:

This means that even when you call inner() later, long after outer has finished running, inner can still access and use outerVar. This is not how typical variables work, as they are usually disposed of after their parent function completes execution.

Closures offer a way to maintain a connection to variables that would otherwise be gone. They keep the spirit of the enclosing context alive, allowing for powerful programming techniques like private variables, callbacks, and more.


Data privacy:

Closures are used to create private variables and encapsulate data. They allow you to expose only necessary functionality to the outer world while keeping internal state hidden.

Callbacks:

Closures are frequently used in asynchronous programming, such as event handlers and callback functions, to maintain context across time gaps.

Functional programming:

Closures enable functional programming techniques like currying and memoization by preserving data between function calls.

Caution:

While closures are powerful, they also require careful consideration of memory management. Since a closure retains references to its enclosing variables, those variables won't be garbage-collected until the closure is no longer accessible. This can lead to memory leaks if closures are not used judiciously.

In a Nutshell

Closures are a powerful tool that can be used for data privacy, callbacks, and functional programming. However, it is important to use closures carefully to avoid memory leaks.

Top comments (2)

Collapse
 
artydev profile image
artydev • Edited

Here is another example : ClosureDemo

Closures are very usefull when you want to create statefull components in UI.
In the following example the state of each counter is maintained through closures.
No global variables (and no hooks :-))

function Counter () {
  let count = 0
  let eltCreate = (tag) => document.createElement(tag)
  function View () {
    let alltags = ["div", "h3", "button", "button"]
    let [div, h3, btninc, btndec] = allElts = alltags.map(eltCreate)
    let incby = (incer) => () => h3.innerText = +h3.innerText + incer
    allElts.slice(1).forEach(child => div.append(child))
    h3.innerText = count
    btninc.innerText = "INC"; btninc.onclick = incby(1) 
    btndec.innerText = "DEC"; btndec.onclick = incby(-1)
    return div
  }
  return View ()
}
[...Array(5)].forEach(() => document.body.append(Counter()))  
Enter fullscreen mode Exit fullscreen mode
Collapse
 
jonrandy profile image
Jon Randy πŸŽ–οΈ

A closure is created whenever a function is created. Being inside another function makes no difference.