क्लोजर
आप स्कोप पहले से जानते हैं: यहाँ से कौन-से नाम दिखते हैं। एक कदम आगे: बाहरी कॉल खत्म होने के बाद भी इनर फ़ंक्शन बाहरी नाम का इस्तेमाल कर सकता है। यही टिकाऊ कड़ी closure (क्लोजर) कहलाती है।
क्लोजर का मतलब
जब एक फ़ंक्शन दूसरे के अंदर बनता है और बाद में भी बाहरी फ़ंक्शन के बाइंडिंग तक पहुँचता है, क्लोजर बनता है। बाहरी कॉल खत्म हो चुकी हो सकती है; इनर फ़ंक्शन उन नामों को अभी भी «याद» रखता है। कोड में शब्द closure नहीं लिखते — नेस्टेड फ़ंक्शन लिखते हैं, और JavaScript ज़रूरी बाहरी बाइंडिंग जीवित रखता है।
तीन हिस्से ध्यान से
📊 बाहरी फ़ंक्शन, बाइंडिंग और इनर फ़ंक्शन
| हिस्सा | भूमिका | शुरुआती संकेत |
|---|---|---|
| बाहरी फ़ंक्शन | एक (या अधिक) बार चलता है और अक्सर इनर लौटाता है | «सेटअप» कॉल |
| बाहरी बाइंडिंग | बाहरी में पैरामीटर या let / const |
वो मान जो इनर को अभी चाहिए |
| इनर फ़ंक्शन | बाद में कॉल करने पर उस बाइंडिंग का उपयोग | वो फ़ंक्शन जो आप रखते हैं |
अगर ये तीन दिखा सकें, लगभग हर शुरुआती क्लोजर उदाहरण समझा सकते हैं। हैरानी नेस्टिंग नहीं — ये है कि बाहरी return के बाद भी बाहरी बाइंडिंग काम आती है।
function makeLine(title) {
function show() {
console.log(title);
}
show();
}
makeLine("Shop");
कॉल के दौरान इनर बाहर देखता है
show के पास लोकल title नहीं। खोज बाहर makeLine तक जाती है और पैरामीटर मिलता है। ये सामान्य नेस्टेड स्कोप है। क्लोजर एक कदम आगे जाता है: makeLine लौटने के बाद के लिए show (या उसकी जुड़वाँ) रखें।
function makeLine(title) {
return function show() {
console.log(title);
};
}
let printShop = makeLine("Shop");
printShop();
बाहरी कॉल खत्म — मेमोरी बनी रही
makeLine("Shop") एक फ़ंक्शन लौटाता है। बाद में printShop कॉल करने पर अभी भी Shop छपता है। उस खत्म कॉल का title पैरामीटर अभी भी पहुँच में है। यही टिकाऊ कैप्चर क्लोजर है।
function makeGreeter(name) {
return function () {
return "Hello, " + name;
};
}
let hiSara = makeGreeter("Sara");
console.log(hiSara());
फ़ैक्टरी तैयार फ़ंक्शन लौटाती है
makeGreeter एक छोटी फ़ैक्टरी है: एक बाहरी कॉल, एक कस्टम फ़ंक्शन वापस। hiSara हमेशा सारा को नमस्कार करता है क्योंकि उसने उसी name पर क्लोज़ किया। makeGreeter का आर्गुमेंट बदलें — नया ग्रीटर, वही पैटर्न, नई मेमोरी।
function makeCounter() {
let n = 0;
return function () {
n = n + 1;
return n;
};
}
let tick = makeCounter();
console.log(tick());
console.log(tick());
काउंटर से लगभग प्राइवेट स्टेट
n बाहरी फ़ंक्शन में रहता है। बाहर का कोड सीधे n नहीं छूता — सिर्फ लौटाया गया फ़ंक्शन कर सकता है। पहली कॉल 1, दूसरी 2। ग्लोबल वेरिएबल के बिना काउंटर «याद» रखता है।
function makeCounter() {
let n = 0;
return function () {
n = n + 1;
return n;
};
}
let a = makeCounter();
let b = makeCounter();
console.log(a());
console.log(a());
console.log(b());
हर बाहरी कॉल की अपनी मेमोरी
a और b अलग-अलग makeCounter() कॉल से आए, इसलिए हर एक का अपना n है। a पर दो कदम b को बीच से शुरू नहीं कराते। क्लोजर अपने आप एक स्टेट बैग शेयर नहीं करते जब तक आप जानबूझकर एक बाहरी बाइंडिंग शेयर न करें।
पेज पर क्लोज़्ड मान दिखाएँ
फ़ैक्टरी से ग्रीटर बनाएँ, एक बार कॉल करें, लौटी स्ट्रिंग पैराग्राफ में लिखें।
<!DOCTYPE html>
<html>
<head>
<title>closures — page</title>
</head>
<body>
<p id="msg">…</p>
<script>
function makeGreeter(name) {
return function () {
return "Hello, " + name;
};
}
let hi = makeGreeter("Omar");
let box = document.getElementById("msg");
box.textContent = hi();
</script>
</body>
</html>
पैराग्राफ Hello, Omar दिखाता है। बाहरी कॉल खत्म; hi अभी भी name जानता है। सिर्फ makeGreeter को दी स्ट्रिंग बदलें, रिफ़्रेश करें, नई पंक्ति पढ़ें। अगला: ऑब्जेक्ट — एक नाम के नीचे जुड़े मान।
अभ्यास
- ऐसा फ़ंक्शन लिखें जो इनर लौटाए और वह बाहरी पैरामीटर लॉग करे।
- लौटे फ़ंक्शन को वेरिएबल में रखें और बाहरी कॉल खत्म होने के बाद कॉल करें।
makeGreeter("Lina")बनाएँ और लौटी स्ट्रिंग लॉग करें।- एक काउंटर बनाएँ; दो बार कॉल करें और
1फिर2देखें। - दो काउंटर बनाएँ; सिर्फ पहले को दो बार बढ़ाएँ और जाँचें कि दूसरा
1से शुरू होता है। - HTML डेमो में सिर्फ नाम आर्गुमेंट बदलें, रिफ़्रेश करें, पैराग्राफ पढ़ें।
आम गलतियाँ
- मानना कि बाहरी लोकल
returnपर तुरंत गायब हो जाते हैं — इनर अभी भी देख सकता है - उम्मीद कि हर
makeCounter()एक हीnशेयर करे — आमतौर पर हर कॉल की अपनी मेमोरी - सोचना कि «क्लोजर» सिर्फ
returnशब्द है —returnइनर दे सकता है, मेमोरी क्लोज़्ड बाइंडिंग है - याद रखने योग्य हर मान ग्लोबल ऑब्जेक्ट पर रखना «सरलता के लिए»
- यहाँ पूरी ऑब्जेक्ट पाठ की उम्मीद — गुणों को एक मान के नीचे बाँधना अगला पेज है
सार
- क्लोजर इनर फ़ंक्शन को बाहरी कॉल खत्म होने के बाद भी बाहरी नाम इस्तेमाल करने देता है
- आप नेस्टेड फ़ंक्शन लिखते हैं; JavaScript ज़रूरी बाइंडिंग जीवित रखता है
- फ़ैक्टरी कस्टम फ़ंक्शन लौटाती है जो सेटअप मान याद रखता है
- काउंटर प्राइवेट
nको लौटे फ़ंक्शन के पीछे छिपाता है - अलग बाहरी कॉल आमतौर पर अलग मेमोरी
- पेज अपडेट क्लोज़्ड नाम से बनी स्ट्रिंग दिखा सकता है
- अगला: ऑब्जेक्ट — एक नाम के नीचे जुड़े मान
🧠 अपने ज्ञान की परीक्षा करें
अपने ज्ञान की परीक्षा करें
इस इंटरैक्टिव क्विज़ के साथ अपनी चुनौती लें और देखें कि आप विषय को कितनी अच्छी तरह समझते हैं
📝 निर्देश
- हर प्रश्न को ध्यान से पढ़ें
- हर प्रश्न के लिए सबसे अच्छा उत्तर चुनें
- आप जितनी बार चाहें क्विज़ दोबारा दे सकते हैं
- आपकी प्रगति शीर्ष पर दिखाई जाएगी