DEV Community

Code Craft-Fun with Javascript
Code Craft-Fun with Javascript

Posted on • Originally published at code-craft.hashnode.dev on

Understanding Closures in JavaScript

Closures are one of the most important Javascript concepts which makes the language more powerful. Closures allow functions to retain access to variables from their parent scope, even after the parent function has finished executing. They provide a powerful way to encapsulate data enabling advanced programming techniques like memoising, currying, implementing higher-order functions, callbacks and more. Before diving further I would recommend you go over the Scope & Scope Chaining concept which will help you understand the closure.

What are Closures?

A closure is a combination of a function enclosed with references to its lexical environment (surrounding state). In Javascript, closures are created every time a function is created.

Consider a function declared inside another function then the inner function forms the Closure with its parent (outer) function. This means that the inner function has access to its scope, its parent function scope and even the global scope.

Why Closures Are Useful?

  1. Data Privacy : Closures allow you to create private variables and functions that are not accessible from the outside. This concept is crucial for building robust and modular code.

  2. Memoisation : Closures enable the creation of function factories that generate customized functions (memoised functions) with preset values. Each generated function retains its own set of variables.

  3. Asynchronous Operations : Closures help preserve the state of variables in asynchronous operations, such as callbacks and event handlers. They ensure that the correct values are available when the function is invoked after any async operation is done.

Due to the closures, Javascript gets the power to implement the code in a more robust way allowing programmers to generate effective design patterns which makes the code more efficient.

Let us understand it with some code examples-

Example Code 1: Creating app counter

function appCounter() {
  let count = 0;

  return function() {
    return ++count;
  };
}

const counter = appCounter();

console.log(counter()); // Output: 1
console.log(counter()); // Output: 2
console.log(counter()); // Output: 3
// ...

Enter fullscreen mode Exit fullscreen mode

Here, the appCounter function creates a closure by returning an inner function. The inner function retains access to the count variable even after appCounter has finished executing. Each time counter is invoked, it increments and returns the count value.

If we want to make the counter start from a particular value we can pass a parameter to appCounter function to initialise a counter variable :

function appCounter(start) {
  let count = start - 1;

  return function() {
    return ++count;
  };
}

const counter = appCounter(10);
console.log(counter()); // Output: 10
console.log(counter()); // Output: 11

Enter fullscreen mode Exit fullscreen mode

Example 2: Implementing Private Variables

function createPerson(name) {
  let username = name;

  return {
    getName: function() {
      return username.toUpperCase();
    }
  };
}

const person = createPerson('John');

console.log(person.getName()); // Output: JOHN
console.log(person.username); // Output: undefined
// can not access the username variable directly

Enter fullscreen mode Exit fullscreen mode

In this example, the createPerson function creates a closure by returning an object with a getName method. The username variable is only accessible through the getName method, making it private and encapsulated within the closure.

Summary:

Closures are a powerful concept in Javascript that allows functions to retain access to variables from their parent scope. They provide a way to encapsulate data and behaviour, enabling advanced techniques such as memoising, currying, implementing higher-order functions, callbacks and more. Understanding closures will enhance your Javascript skills and empower you to write more robust and efficient code. Start exploring the world of closures and unlock the true potential of Javascript functions!

Top comments (2)

Collapse
 
jonrandy profile image
Jon Randy πŸŽ–οΈ

If a function is declared inside another function then the inner function forms the Closure with its parent (outer) function. This means that the inner function has access to its scope, its parent function scope and even the global scope.

This is correct, but ALL functions form closures with their lexical scope. The function being defined inside another function is irrelevant.

Collapse
 
codecraftjs profile image
Code Craft-Fun with Javascript • Edited

Hello @jonrandy ,
Thanks for pointing out this. Completely agreed! :)
Just to clarify, "function inside a function" was just an example to start with closure. As mentioned at the very beginning with a blog link, we need to understand scope & scope chaining / lexical scopes before diving into the Closures. I will edit this to be more clear to all .