Computer >> कंप्यूटर >  >> प्रोग्रामिंग >> Javascript

वेब फंडामेंटल्स:स्कोप और जावास्क्रिप्ट क्लोजर - एक प्राइमर

जावास्क्रिप्ट भाषा में सबसे बड़े buzzwords में से एक क्लोजर है। यह FAANG कंपनियों में नौकरी के लिए इंटरव्यू के कई सवालों का विषय है। इस लेख में, हम क्लोजर और स्कोप के बारे में बात करेंगे, इसकी अवधारणाओं को सरल उदाहरणों के साथ स्पष्ट करेंगे, और फिर एक बड़े तकनीकी दिग्गज के साथ एक साक्षात्कार से एक नमूना प्रश्न के साथ समाप्त करेंगे।

दायरा

जब कोई आपको बताता है कि कुछ परियोजना के दायरे में है या नहीं, तो इसका क्या मतलब है?

जब मैं इसका उत्तर सोचता हूं तो मैं एक पेरिस्कोप या दूरबीन के बारे में सोचना चाहता हूं। ये उपकरण हमें उसके पास मौजूद लेंस की सीमा के भीतर सभी प्रकार की चीजें दिखाते हैं:यह दायरे में है . अगर यह दायरे के बाहर है , आप लेंस के व्यास से आगे नहीं देख सकते हैं। और व्यास के बाहर किसी चीज पर प्रकाश डालना संभव नहीं है। आपको इसके बारे में सोचना चाहिए क्योंकि हम जावास्क्रिप्ट में तीन बहुत महत्वपूर्ण और विशिष्ट प्रकार के दायरे के बारे में बात करते हैं:स्थानीय, वैश्विक और शाब्दिक।

स्थानीय दायरा

आज हम जिन तीन क्षेत्रों के बारे में बात करेंगे, उनमें से स्थानीय दायरा सबसे छोटा है। जब हम कोई फ़ंक्शन घोषित करते हैं, तो कोष्ठक ({}) के अंदर कुछ भी फ़ंक्शन के लिए स्थानीय माना जाता है। जब जावास्क्रिप्ट इंजन फ़ंक्शन को पढ़ता है तो यह चर घोषित करेगा; जब यह समाप्त होता है तो यह चर को नष्ट कर देगा।

function greeting() {
 var websiteName = 'Career Karma';
 return `Hello ${websiteName}`;
}
 
console.log(greeting()); // Hello Career Karma
console.log(websiteName); // ReferenceError: websiteName is not defined

जैसा कि आप देख सकते हैं, जब हम बुलाए गए ग्रीटिंग फ़ंक्शन के परिणाम "console.log ()" करते हैं, तो हम फ़ंक्शन निष्पादित होने के बाद वेबसाइटनाम तक पहुंचने में सक्षम होते हैं। यह हमें 'हैलो करियर कर्मा' स्ट्रिंग देता है जिसकी हमें तलाश थी। console.log() फ़ंक्शन के अंदर घोषित किया गया चर एक त्रुटि फेंकता है क्योंकि यह परिभाषित नहीं है।

जैसा कि पहले ही उल्लेख किया गया है, वेबसाइटनाम अपरिभाषित क्यों है, क्योंकि वेरिएबल फ़ंक्शन के अंदर बनाए जाते हैं जब उन्हें बुलाया जाता है और फिर टर्मिनल स्टेटमेंट चलने पर नष्ट हो जाता है। फ़ंक्शन के बाहर किसी भी चीज़ की फ़ंक्शन के अंदर की सामग्री तक पहुंच नहीं होती है, जब तक कि उसके पास कोई विशेष सेटअप न हो।

वैश्विक दायरा

यह अगला दायरा काफी हद तक वाक्यांश का शाब्दिक अनुवाद है। एक वैश्विक दायरा एक समारोह के बाहर घोषित वस्तुओं को लेता है और उन्हें एक ऐसे स्थान पर सुरक्षित रखता है जहां सभी स्क्रिप्ट और विधियां और कार्य उनके तर्क के लिए उनका उपयोग और उपयोग कर सकते हैं।

 
let counter = 0; // global -- declared outside function
 
const add = () => { // function declaration
   let counter = 0; // local -- declared inside function
   counter += 1; 
   // counter increased by 1 -- which counter variable increased?
   return counter;
}
 
add(); // invoke
add(); //  three
add(); //  times
console.log(counter) // is this 3 or 0? Why? 

यदि हम console.log() कोड के अंत में काउंटर? आप क्या होने की उम्मीद करते हैं?

81% प्रतिभागियों ने कहा कि बूटकैंप में भाग लेने के बाद उन्हें अपनी तकनीकी नौकरी की संभावनाओं के बारे में अधिक आत्मविश्वास महसूस हुआ। आज ही एक बूटकैंप से मिलान करें।

बूटकैंप शुरू करने से लेकर अपनी पहली नौकरी खोजने तक, औसत बूटकैंप ग्रेड ने करियर संक्रमण में छह महीने से भी कम समय बिताया।

आइए कोड के माध्यम से चलते हैं:

  1. वैश्विक परिवेश में काउंटर वैरिएबल घोषित और आरंभ किया गया।
  2. वैश्विक वातावरण में घोषित फ़ंक्शन जोड़ें।
  3. जोड़ना शुरू हो गया है।
  4. काउंटर वैरिएबल घोषित और स्थानीय वातावरण में शुरू किया गया।
  5. स्थानीय काउंटर में 1 की वृद्धि होती है, स्थानीय और वैश्विक क्यों नहीं?
  6. काउंटर लौटा दिया गया है। समारोह समाप्त हो जाता है।
  7. जोड़ें फिर से लागू हो गई हैं
  8. चरण 4 से 6 तक फिर से चलें।
  9. चरण 3 से 6 फिर से दोहराएं।
  10. console.log(counter); क्या लौटाया गया है?

क्योंकि फ़ंक्शन समाप्त हो जाता है जब काउंटर हर बार 1 पर होता है, हमारे स्थानीय काउंटर वैरिएबल को हर बार फ़ंक्शन के चलने पर 0 पर फिर से शुरू किया जाता है। चाहे कुछ भी हो जाए, स्थानीय स्तर पर काउंटर हमेशा 1 पर रुकेगा।

यदि कोई फ़ंक्शन अपने दायरे में एक चर पाता है, तो यह चर के वैश्विक दायरे को नहीं देखता है - इसलिए वैश्विक चर कभी नहीं बदलता है। तो, हमारा console.log() आउटपुट 0 होगा क्योंकि उस कथन के वातावरण के भीतर हमारा निकटतम परिभाषित चर वैश्विक वातावरण में है।

लेक्सिकल स्कोप

लेक्सिकल स्कोप जावास्क्रिप्ट में सबसे मौलिक अवधारणाओं में से एक है। यह विचार है कि किसी फ़ंक्शन या चर का निर्माण कोड के कुछ हिस्सों तक पहुंच योग्य होगा और फिर कोड के अन्य हिस्सों तक पहुंच योग्य नहीं होगा। यह सब इस बात पर निर्भर करता है कि प्रत्येक चर और कार्य की घोषणा कहाँ है।

आइए कोड के इस ब्लॉक पर एक नज़र डालें:

const init = () => { // <== This is our outer function
 const var1 = 'Career'; // outer scope
 const second = () => { // <== This is our inner function
   const var2 = 'Karma'; // inner scope
   console.log(var1); // Career
   console.log(var2); // Karma
   return var1 + " " + var2;
 };
 
 // console.log(var2); // undefined
 
 
 return second();
};
init();
 

यहां हमारे पास नेस्टेड फ़ंक्शंस का एक सेट है। init() फ़ंक्शन var1 नामक एक चर घोषित करता है, दूसरे नामक फ़ंक्शन की घोषणा करता है और second() . को आमंत्रित करता है .

जब कंपाइलर पहली बार इस कोड से गुजरता है, तो यह हमारे पास जो कुछ है उस पर एक उच्च स्तरीय नज़र डालता है:

  1. init() समारोह
  2. आह्वान init()

इस बिंदु पर, हम init () फ़ंक्शन के अंदर और कुछ नहीं देख सकते हैं - हम जानते हैं कि फ़ंक्शन मौजूद है। जब हमारे init () func को लागू किया जाता है, तो कंपाइलर फ़ंक्शन के अंदर क्या है, इस पर एक और उच्च स्तरीय नज़र डालता है:

  1. var1
  2. second() समारोह
  3. आह्वान second()

init() फ़ंक्शन के बारे में कुछ भी नहीं जानता है कि second() . के अंदर क्या हो रहा है खंड मैथा। यह केवल वही देख सकता है जो इसके व्याख्यात्मक वातावरण . में है - इसके आसपास की स्थिति।

प्रत्येक नेस्टेड फ़ंक्शन एक छोटे कंटेनर में होता है, जैसे उन रूसी matryoshka नेस्टिंग गुड़िया का एक सेट (उदाहरण के लिए पृष्ठ के शीर्ष देखें यदि आप सुनिश्चित नहीं हैं कि वे क्या हैं)। गुड़िया केवल इस बारे में जानती हैं कि उनके कंटेनर के अंदर क्या चल रहा है और माता-पिता में पहले से क्या हुआ या घोषित / पढ़ा गया है। उदाहरण के लिए सबसे बड़ी गुड़िया केवल यह जानती है कि उसके कंटेनर में अगली गुड़िया मौजूद है। यह सेट में किसी भी अन्य गुड़िया के बारे में नहीं जानता है, बस इसके शाब्दिक वातावरण (इसकी स्थिति) में क्या है और पहले से क्या हुआ है (बाहरी दायरा)।

संक्षेप में, हम दो बातें जानते हैं:

  1. बाहरी दायरा भीतरी दायरा नहीं देख सकता।
  2. आंतरिक दायरे की बाहरी दायरे तक पहुंच है।

क्योंकि बाहरी सामना नहीं देख सकता कि आंतरिक दायरे में क्या हो रहा है, हम सुरक्षित रूप से कह सकते हैं कि यह एकतरफा संबंध है। आंतरिक बाहरी दायरे से चर देख और उपयोग कर सकता है, लेकिन बाहरी आंतरिक नहीं देख सकता है। इसे लेक्सिकल स्कोप . कहा जाता है .

लेक्सिकल स्कोपिंग की सुंदरता यह है कि एक चर का मान कोड में उसके स्थान से निर्धारित होता है। फ़ंक्शन पहले अपने स्थानीय वातावरण के अंदर एक चर के अर्थ की तलाश करते हैं - यदि वह इसे नहीं ढूंढ पाता है, तो यह उस फ़ंक्शन पर चला जाता है जो उस फ़ंक्शन को परिभाषित करता है। यदि यह वहां नहीं मिलता है, तो यह श्रृंखला को अगले परिभाषित फ़ंक्शन तक ले जाता है।

यह जावास्क्रिप्ट में एक बहुत ही महत्वपूर्ण अवधारणा बन जाती है जो बार-बार सामने आएगी जब आप जावास्क्रिप्ट फ्रेमवर्क के बारे में अधिक जानेंगे और वे कैसे काम करेंगे। आप बाहर से नीचे जा सकते हैं, लेकिन आप दूसरी दिशा में कभी भी "ऊपर" नहीं जा सकते। यह बहुत महत्वपूर्ण है क्योंकि हम मुख्य विषय पर आते हैं:बंद करें

बंद

क्लोजर की परिभाषा लेक्सिकल स्कोप से काफी मिलती-जुलती है। दोनों के बीच मुख्य अंतर यह है कि क्लोजर एक उच्च क्रम का कार्य है और लेक्सिकल स्कोपिंग नहीं है। एक उच्च क्रम फ़ंक्शन में एक मूल विशेषता होती है:यह या तो एक फ़ंक्शन देता है या किसी फ़ंक्शन को पैरामीटर के रूप में उपयोग करता है।

क्लोजर एक ऐसा फंक्शन है जो अपने लेक्सिकल स्कोप तक पहुंच सकता है, तब भी जब उस फंक्शन को बाद में लागू किया जा रहा हो।

क्लोजर और लेक्सिकल स्कोप दोनों के अपने वेरिएबल हैं, पैरेंट फंक्शन के वेरिएबल्स और पैरामीटर्स तक पहुंच सकते हैं, और ग्लोबल वेरिएबल्स का उपयोग कर सकते हैं। आइए निम्नलिखित कोड के माध्यम से चलते हैं:

function greeting() { //outer scope (parent function)
 const userName = "CrrKrma1952"; // parent variable
 function welcomeGreeting() { // inner function
   console.log("Hello, " + userName); // accesses parent var
   return "Hello, " + userName; // terminal statement
 }
 return welcomeGreeting; // returns a function (which makes it HOF)
} // end of greeting()
 
const greetUser = greeting(); //
greetUser(); //  Hello, CrrKrma1952
  1. greeting() फ़ंक्शन मौजूद है, लेकिन हम अभी तक सामग्री को नहीं जानते हैं।
  2. greetUser मौजूद है, लेकिन अभी तक सामग्री नहीं जानता
  3. greetUser() - यह पिछली पंक्ति को आमंत्रित करता है, जो बदले में, ग्रीटिंग () फ़ंक्शन को आमंत्रित करता है।
  4. उपयोगकर्ता नाम घोषित
  5. welcomeGreeting() मौजूद है, लेकिन अभी तक सामग्री नहीं जानता
  6. वापसी विवरण welcomeGreeting() . के नीचे ब्लॉक वही फ़ंक्शन देता है
  7. console.log(‘Hello, ‘ + userName); यहां हमारा कंसोल.लॉग उपयोगकर्ता नाम का मान प्राप्त करने के लिए पैरेंट स्कोप तक पहुंच सकता है
  8. टर्मिनल स्टेटमेंट जो फ़ंक्शन को समाप्त करता है और कोड ब्लॉक के अंदर चर के अर्थ को नष्ट कर देता है।

इस कोड में, हम एक साथ नेस्टिंग फंक्शन द्वारा सूचनाओं को प्रसारित कर रहे हैं ताकि बाद में पैरेंट स्कोप तक पहुँचा जा सके।



निष्कर्ष

इस लेख में, हमने एक बहुत ही भारी जावास्क्रिप्ट विषय के बारे में बात की:स्कोप और क्लोजर। मैं इस विषय पर कई अलग-अलग लेख पढ़ने और पढ़ने की सलाह दूंगा। जिस तरह से इसे पढ़ाया जाता है वह विभिन्न दृष्टिकोणों से आ सकता है - जिसका अर्थ है, निश्चित रूप से, इसे सीखने के बहुत सारे तरीके हैं। मुझे आशा है कि यह प्राइमर आपके लिए मददगार था! क्लोजर पर अपना अध्ययन जारी रखने के लिए शुभकामनाएँ!


  1. जावास्क्रिप्ट में डिफॉल्ट और रेस्ट पैरामीटर्स के साथ इफेक्टिव फंक्शन सिग्नेचर

    जावास्क्रिप्ट में डिफॉल्ट और रेस्ट पैरामीटर के साथ फंक्शन सिग्नेचर को लागू करने के लिए कोड निम्नलिखित है - उदाहरण <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-

  1. जावास्क्रिप्ट में फंक्शन प्रोटोटाइप

    जावास्क्रिप्ट में बनाए गए कार्यों में हमेशा जावास्क्रिप्टइंजिन द्वारा जोड़ा गया प्रोटोटाइप गुण होता है। प्रोटोटाइप प्रॉपर्टी एक ऑब्जेक्ट है जिसमें डिफ़ॉल्ट रूप से कंस्ट्रक्टर प्रॉपर्टी होती है। फंक्शन प्रोटोटाइप को − . द्वारा एक्सेस किया जा सकता है functionName.prototype जब फ़ंक्शन कंस्ट्रक्टर का उ

  1. जावास्क्रिप्ट में फंक्शन उधार।

    जावास्क्रिप्ट में विधियों को उधार लेने के लिए कॉल (), लागू () और बाइंड () का उपयोग किया जाता है। जावास्क्रिप्ट में उधार लेने के तरीकों के लिए कोड निम्नलिखित है - उदाहरण <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="v