JavaScript Closures Kya Hota Hai?

JavaScript ke ek powerful feature ko samjhein jo data privacy aur complex functions banane me madad karta hai.

Closures ka Introduction

JavaScript mein, closure ek aisi concept hai jisme ek inner function apne outer function ke variables aur scope ko access kar sakta hai, bhale hi outer function apna execution complete kar chuka ho. Jab ek function doosre function ke andar define hota hai aur woh apne parent ke scope ke variables ko "yaad" rakhta hai, to usse closure kehte hain.

Basic Closure Example

function outerFunction() {
  let outerVariable = 'I am from the outer function';

  function innerFunction() {
    console.log(outerVariable); // Accessing the outer scope
  }

  return innerFunction;
}

const myClosure = outerFunction(); // outerFunction has finished executing
myClosure(); // Output: 'I am from the outer function'

How it Works (Lexical Scoping)

JavaScript lexical scoping use karta hai, jiska matlab hai ki ek function ka scope uske code me uski physical position se decide hota hai. `innerFunction` jab create hua, tab usne apne parent (`outerFunction`) ke scope (aur uske variables jaise `outerVariable`) ka reference "lock" kar liya. Isliye, jab `outerFunction` execute ho kar khatm ho gaya, tab bhi `innerFunction` (jo ab `myClosure` variable me hai) apne parent ke variables ko access kar pa raha hai.

Common Use Cases of Closures

1. Data Encapsulation and Private Variables

Closures ka sabse powerful use data ko private banane ke liye hota hai. Aap aise variables create kar sakte hain jo bahar se direct access nahi kiye ja sakte, sirf aapke diye gaye functions se hi manipulate ho sakte hain.

function createCounter() {
  let count = 0; // This is a private variable

  return {
    increment: function() {
      count++;
      console.log(count);
    },
    decrement: function() {
      count--;
      console.log(count);
    },
    getCount: function() {
      return count;
    }
  };
}

const myCounter = createCounter();
myCounter.increment(); // Output: 1
myCounter.increment(); // Output: 2
console.log(myCounter.count); // Output: undefined (cannot access private variable)

Is example me, `count` variable `createCounter` ke scope tak limited hai. Hum use direct access nahi kar sakte, sirf `increment` aur `decrement` methods ke through hi change kar sakte hain.

2. Callback Functions & Event Handlers

Jab aap `setTimeout` ya `addEventListener` jaise asynchronous operations me callback function pass karte hain, tab closures automatically ban jaate hain. Callback function apne surrounding scope ke variables ko yaad rakhta hai.

function setupAlert(message) {
    setTimeout(function() {
        alert(message); // Remembers the 'message' variable
    }, 2000);
}
setupAlert("This is a delayed message!");

3. Currying

Currying ek functional programming technique hai jisme ek function jo multiple arguments leta hai, use aise sequence of functions me toda jaata hai jo ek-ek karke argument lete hain. Closures is technique ko possible banate hain.

function multiply(a) {
  return function(b) { // This inner function is a closure
    return a * b;
  };
}

const multiplyByTwo = multiply(2); // Creates a new function that multiplies by 2
console.log(multiplyByTwo(5)); // Output: 10
console.log(multiplyByTwo(10)); // Output: 20

Closures in Loops: A Common Pitfall

Loops me closure use karte waqt ek common problem aati hai, khaas kar `var` ke saath.

for (var i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log(i); // Always prints 3
  }, 100);
}
// Output: 3, 3, 3

Aisa isliye hota hai kyunki `var` function-scoped hai. Loop ke khatm hone tak `i` ki value `3` ho jaati hai, aur sabhi `setTimeout` callbacks usi `i` ke single reference ko share kar rahe hote hain. Is problem ko solve karne ke liye ES6 me `let` introduce kiya gaya jo block-scoped hai.

for (let i = 0; i < 3; i++) { // 'let' creates a new binding for each iteration
  setTimeout(function() {
    console.log(i); // Prints 0, 1, 2 correctly
  }, 100);
}
// Output: 0, 1, 2

Key Takeaways

  • Closure tab banta hai jab ek function apne lexical scope (parent function ke variables) ko access karta hai.
  • Yeh function ko "yaad" rakhne ki power deta hai, bhale hi parent function execute ho chuka ho.
  • Closures ka use data encapsulation (private variables), callbacks, aur currying jaise patterns ke liye hota hai.
  • Loops me `var` ke saath closure use karne se unexpected results aa sakte hain; iske liye `let` ka use karein.
  • Closures memory use karte hain, isliye agar unhe sahi se manage na kiya jaaye toh memory leaks ho sakte hain.
Bonus: Practical Application!
Ab in concepts ko practically use karke dekhein.

Ek "private" variable banane ki koshish karein jise sirf ek function ke through hi access ya modify kiya ja sake.

Practice in JS Editor
Test Your Knowledge!
Kya aap JavaScript Closures ke baare mein seekh chuke hain? Chaliye dekhte hain!

Apni knowledge test karne ke liye is quick quiz ko dein.

Start Quiz