Skip to main content

Command Palette

Search for a command to run...

JavaScript Closures Explained: How Functions Remember Their Origin

Published
JavaScript Closures Explained: How Functions Remember Their Origin

What is the problem In below the code ?

function myFunction(){
  const name = "Mozila";
  return function displayName(){
    console.log(name);    
  }
}

const myName = myFunction();
myName()

We are returning a function from myFunction. In this returned function, I would expect to only have access to what is declared inside it. Ideally, I shouldn't have access to the name variable since it's not declared within displayName. However, I still have access to it.

In the problem below, we are trying to control the result. But how ?

function eternal(guest) {
  let count = 0;
  
  function zomato() {
    console.log(`Hi ${guest} from Zomato`);
    return;
  }
  
  function blinkit() {
    if (count === 1) return;
    console.log(`Hi ${guest} from Blinkit`);
    count++;
  }
  
  return {
    zomato,
    blinkit
  };
}

const ram = eternal("Ram");
console.log(ram.zomato());
console.log(ram.blinkit());
console.log(ram.blinkit());
console.log(ram.blinkit());

In the above function, we are accessing the closure variables guest and count. Normally, local variables are destroyed after execution β€” they are garbage collected. When functions still hold the reference to those variables, JavaScript preserves the reference in the form of a closure. A good example is Higher-Order Functions (HOF) like map. While iterating, map remembers those values in the form of a closure.

What is lexical scope ?

Lexical scoping is the mechanism where inner functions have access to variables defined in their outer scopes When a variable is referenced, JavaScript searches for its declaration starting from the current scope, then moving outward to parent scopes, and finally to the global scope. This hierarchical search pattern is called lexical scope.

Can the below definition fit for "What is a closure?"

A closure is a feature in JavaScript where a function can remember variables from its outer function, even after the outer function has finished running. A closure refers to the lexical scope in which a function was declared and the variables it has access to. When we create a function inside another function, JavaScript automatically creates a closure. This means:

  1. The inner function can access variables of the outer function.

  2. Even if the outer function has already finished execution, those variables are still remembered.

  3. These variables are not available globally β€” only the inner function can use them. In other words, a closure gives a function access to its outer scope whenever we create a function.

In other words, a closure gives a function access to its outer scope whenever we create a function

What is difference between Private # and Closure?

1. Private Fields (#balance)

class Bank {
  #balance = 0;

  deposite(amt){
    this.#balance += amt
  }

  balance(){
    return this.#balance
  }
}

How it works

  • #balance is stored inside the instance

  • Only accessible inside the class

  • Enforced by JavaScript engine (hard private)

❌ Not accessible outside

hdfc.#balance // ❌ Syntax Error
hdfc.balance  // ❌ undefined (it's a method, not property)

βœ… Characteristics

  • True encapsulation

  • Part of OOP (class-based)

  • Cleaner & modern

  • Cannot be accessed or hacked easily

2. Closure (Function-based privacy)

function Bank() {
  let balance = 0;

  return {
    deposite(amt) {
      balance += amt;
    },
    getBalance() {
      return balance;
    }
  };
}

const hdfc = Bank();

How it works

  • balance is stored in function scope

  • Inner functions remember it β†’ closure


❌ Not accessible outside

hdfc.balance // undefined

βœ… Characteristics

  • Uses lexical scope

  • Functional programming style

  • More flexible

  • Can be accidentally exposed

πŸ”₯ Key Differences

Feature Private (#) Closure
Type OOP (class) Functional
Storage Inside object Inside function scope
Access Only class methods Inner functions
Security πŸ”’ Strong (syntax enforced) ⚠️ Medium
Debugging Easy Hard sometimes
Performance Better for many instances Can create multiple copies