ग्लोबल और लोकल वैरिएबल स्कोप

इस लेख में, इसके दायरे और JavaScript में इसके काम करने के तरीके के बारे में बताया गया है.

स्कोप, JavaScript और दूसरी प्रोग्रामिंग भाषाओं में एक बुनियादी सिद्धांत है जो उस कॉन्टेक्स्ट को तय करता है जिसमें वैरिएबल को ऐक्सेस और इस्तेमाल किया जाता है. जैसे-जैसे आप JavaScript सीखते जाते हैं और वैरिएबल के साथ ज़्यादा काम करते जाते हैं, यह आपके कोड के लिए ज़्यादा फ़ायदेमंद और लागू होने वाला होता जाता है.

दायरे से आपको इन कामों में मदद मिल सकती है:

  • मेमोरी का बेहतर तरीके से इस्तेमाल करना: स्कोप की मदद से, वैरिएबल को ज़रूरत के मुताबिक ही लोड किया जा सकता है. अगर कोई वैरिएबल दायरे से बाहर है, तो आपको उसे अभी चल रहे कोड में उपलब्ध कराने की ज़रूरत नहीं है.
  • गड़बड़ियों को ज़्यादा आसानी से ढूंढना और उन्हें ठीक करना: लोकल स्कोप वाले वैरिएबल को आइसोलेट करने से, अपने कोड में गड़बड़ियां आसानी से हल की जा सकती हैं. इसकी वजह यह है कि ग्लोबल वैरिएबल के उलट, यह भरोसा किया जा सकता है कि बाहरी स्कोप वाला कोड, लोकल स्कोप वाले वैरिएबल में बदलाव नहीं कर सकता.
  • फिर से इस्तेमाल किए जा सकने वाले कोड के छोटे ब्लॉक बनाएं: उदाहरण के लिए, कोई प्योर फ़ंक्शन लिखा जा सकता है जो बाहरी स्कोप पर निर्भर नहीं रहता. इस तरह के फ़ंक्शन को आसानी से कहीं और ले जाया जा सकता है. इसके लिए, कम से कम बदलाव करें.

स्कोप क्या होता है?

वैरिएबल का स्कोप तय करता है कि कोड के अंदर कहां से वैरिएबल का इस्तेमाल किया जा सकता है.

JavaScript ग्लोबल या लोकल स्कोप के वैरिएबल के बारे में बताता है:

  • ग्लोबल स्कोप वाले वैरिएबल, JavaScript कोड के अन्य सभी दायरों में उपलब्ध होते हैं.
  • स्थानीय स्कोप वाले वैरिएबल सिर्फ़ किसी खास स्थानीय कॉन्टेक्स्ट में उपलब्ध होते हैं और उन्हें var, let, और const जैसे कीवर्ड से बनाया जाता है. अगर किसी फ़ंक्शन में वैरिएबल बनाने के लिए var, let या const कीवर्ड का इस्तेमाल किया जाता है, तो उस वैरिएबल में लोकल स्कोप होता है.

इस लेख के आगे के सेक्शन में ब्लॉक और लेक्सिकल स्कोप के बारे में बताया गया है:

  • ब्लॉक स्कोप वैरिएबल, किसी ब्लॉक के लिए स्थानीय तौर पर उपलब्ध होता है. यह वैरिएबल कर्ली ब्रैकेट की जगह से तय होता है, जहां ब्लॉक स्टेटमेंट सेट किया गया है. सिर्फ़ let या const कीवर्ड के साथ तय किए गए वैरिएबल में ही ब्लॉक का दायरा होता है.
  • लेक्सिकल स्कोप में उस जगह का इस्तेमाल किया जाता है जहां सोर्स कोड में किसी वैरिएबल की जानकारी दी जाती है. इससे यह तय किया जाता है कि वह वैरिएबल कहां उपलब्ध है. आउटर स्कोप में रेफ़र किए गए लेक्सिकल एनवायरमेंट के वैरिएबल का पूरा फ़ंक्शन ऐक्सेस देने के लिए, क्लोज़र का इस्तेमाल किया जाता है.

जब किसी वैरिएबल को इसके दायरे में ऐक्सेस किया जाता है, तो JavaScript उस वैरिएबल की असाइन की गई वैल्यू दिखाता है या गड़बड़ी जनरेट करता है.

किसी वैरिएबल का एलान करने के लिए:

  • लोकल या ग्लोबल स्कोप वैरिएबल का एलान करने के लिए, var, const या let कीवर्ड का इस्तेमाल करें.
  • ब्लॉक-स्कोप वैरिएबल का एलान करने के लिए, const या let कीवर्ड का इस्तेमाल करें.

जब किसी फ़ंक्शन में var वैरिएबल का एलान किया जाता है, तो यह एलान उस वैरिएबल को सबसे नज़दीकी एनक्लोज़िंग फ़ंक्शन के लिए उपलब्ध कराता है. ब्लॉक स्कोप वाले वैरिएबल का एलान करने के लिए, var कीवर्ड का इस्तेमाल नहीं किया जा सकता.

दायरे के उदाहरण

यह उदाहरण ग्लोबल स्कोप के बारे में बताता है, क्योंकि greeting वैरिएबल का एलान किसी भी फ़ंक्शन या ब्लॉक के बाहर किया गया है. इससे इसकी वैल्यू, मौजूदा दस्तावेज़ में मौजूद सभी कोड के लिए उपलब्ध हो जाती है:

const greeting = 'hello';
console.log(greeting); // 'hello'

ग्लोबल-स्कोप के उदाहरण में, greeting वैरिएबल को hello वैल्यू असाइन की गई है.

यह उदाहरण लोकल स्कोप के बारे में बताता है, क्योंकि यह किसी फ़ंक्शन में let कीवर्ड के साथ greeting वैरिएबल के बारे में बताता है. greeting वैरिएबल, लोकल स्कोप वाला वैरिएबल है. यह फ़ंक्शन के बाहर उपलब्ध नहीं है.

function greet() {
  let greeting = 'Hello World!';
  console.log(greeting);
}

इस उदाहरण में ब्लॉक के स्कोप के बारे में बताया गया है, क्योंकि यह किसी ब्लॉक में greeting वैरिएबल के बारे में बताता है, ताकि वैरिएबल को सिर्फ़ कर्ली ब्रैकेट में ऐक्सेस किया जा सके:

if (true) {
   const greeting = 'hello';
}

console.log(greeting); // ReferenceError: greeting is not defined

ध्यान दें कि जब console.log फ़ंक्शन, greeting वैरिएबल की वैल्यू दिखाने की कोशिश करता है, तो JavaScript अनुमानित hello मैसेज के बजाय, ReferenceError गड़बड़ी का मैसेज दिखाता है. क्यों?

गड़बड़ी का एक मैसेज मिला है, क्योंकि greeting वैरिएबल में ब्लॉक का दायरा है और सबसे नज़दीकी ब्लॉक, if कंडिशनल स्टेटमेंट का हिस्सा है. आपने जिन let और const वैरिएबल का एलान किया है उन्हें ब्लॉक के बाहर से ऐक्सेस नहीं किया जा सकता. इस तरह, आपके पास सिर्फ़ कर्ली ब्रैकेट में ही greeting वैरिएबल को ऐक्सेस करने का विकल्प होता है. इससे, ब्लॉक के स्कोप की जानकारी मिलती है.

इस उदाहरण में गड़बड़ी ठीक कर दी गई है, क्योंकि यह console.log(message) तरीके को कर्ली ब्रैकेट में ले जाता है. अपडेट किया गया कोड, ब्लॉक में console.log(message) तरीके को बदल देता है.

if (true) {
   const greeting = 'hello';
   console.log(greeting);
}

स्कोप के टाइप

ग्लोबल स्कोप

ग्लोबल स्कोप वाले वैरिएबल को प्रोग्राम में कहीं से भी ऐक्सेस किया जा सकता है.

ऐसी एचटीएमएल फ़ाइल इस्तेमाल करें जो दो JavaScript फ़ाइलें इंपोर्ट करती हो: file-1.js और file-2.js:

<script src="file-1.js"></script>
<script src="file-2.js"></script>

इस उदाहरण में, globalMessage वैरिएबल का ग्लोबल स्कोप है और इसे फ़ंक्शन के बाहर लिखा गया है. चलाने और लागू करने के दौरान, JavaScript प्रोग्राम में कहीं से भी globalMessage वैरिएबल की वैल्यू को ऐक्सेस किया जा सकता है.

इस कोड स्निपेट में file-1.js और file-2.js फ़ाइलों का कॉन्टेंट देखा जा सकता है. दोनों फ़ाइलों में, globalMessage वैरिएबल की उपलब्धता पर ध्यान दें.

// file-1.js
function hello() {
    var localMessage = 'Hello!';
}

var globalMessage = 'Hey there!';

// file-2.js
console.log(localMessage); // localMessage is not defined
console.log(globalMessage); // Hey there!

यहां एक और तरह का स्कोप है, जिसकी जानकारी इस लेख में नहीं दी गई है. अगर किसी JavaScript मॉड्यूल में ऐसा वैरिएबल बनाया जाता है जो फ़ंक्शन या ब्लॉक से बाहर होता है, तो उसमें ग्लोबल स्कोप नहीं होता, बल्कि मॉड्यूल का स्कोप होता है. मॉड्यूल के स्कोप वाले वैरिएबल, मौजूदा मॉड्यूल में कहीं भी उपलब्ध होते हैं, लेकिन अन्य फ़ाइलों या मॉड्यूल में उपलब्ध नहीं होते. मॉड्यूल के स्कोप वाले वैरिएबल को अन्य फ़ाइलों में उपलब्ध कराने के लिए, आपको इसे उस मॉड्यूल से एक्सपोर्ट करना होगा जहां इसे बनाया गया है. इसके बाद, इसे उस मॉड्यूल से import करें जिसके लिए वैरिएबल को ऐक्सेस करना ज़रूरी है.

लोकल स्कोप और फ़ंक्शन का स्कोप

जब किसी JavaScript फ़ंक्शन में var, let या const कीवर्ड के साथ वैरिएबल बनाए जाते हैं, तो वैरिएबल, फ़ंक्शन के लिए स्थानीय होते हैं. इसलिए, उन्हें सिर्फ़ फ़ंक्शन में से ऐक्सेस किया जा सकता है. लोकल वैरिएबल तब बनाए जाते हैं, जब फ़ंक्शन शुरू होता है. साथ ही, फ़ंक्शन का इस्तेमाल पूरा होने के बाद, वे सही तरीके से मिट जाते हैं.

यह उदाहरण, addNumbers() फ़ंक्शन में total वैरिएबल के बारे में बताता है. आपके पास addNumbers() फ़ंक्शन में सिर्फ़ a, b,, और total वैरिएबल को ऐक्सेस करने का विकल्प है.

function addNumbers(a, b) {
    const total = a + b;
}

addNumbers(3, 4);

वैरिएबल को नाम देने के लिए, let और const कीवर्ड का इस्तेमाल किया जा सकता है. let कीवर्ड का इस्तेमाल करने पर, JavaScript वैरिएबल को अपडेट कर सकता है. हालांकि, const कीवर्ड के साथ वैरिएबल स्थिर बना रहता है.

var variable1 = 'Declared with var';
var variable1 = 'Redeclared with var';
variable1; // Redeclared with var

let variable2 = 'Declared with let. Cannot be redeclared.';
variable2 = 'let cannot be redeclared, but can be updated';
variable2; // let cannot be redeclared, but can be updated

const variable3 = 'Declared with const. Cannot be redeclared or updated';
variable3; // Declared with const. Cannot be redeclared or updated

दायरा ब्लॉक करें

ब्लॉक का इस्तेमाल किसी एक स्टेटमेंट या कुछ स्टेटमेंट को एक साथ ग्रुप करने के लिए किया जाता है. किसी ब्लॉक-स्कोप वाले लोकल वैरिएबल का एलान करने के लिए, const या let कीवर्ड का इस्तेमाल किया जा सकता है. ध्यान दें कि ब्लॉक स्कोप वाले वैरिएबल का एलान करने के लिए, var कीवर्ड का इस्तेमाल नहीं किया जा सकता.

उदाहरण के लिए, इस ब्लॉक में name वैरिएबल का स्कोप और इसकी "Elizabeth" वैल्यू, कर्ली ब्रैकेट में शामिल होती है. किसी ब्लॉक के दायरे में आने वाले वैरिएबल, ब्लॉक के बाहर उपलब्ध नहीं होते.

{
    const name = "Elizabeth";
}

if, for या while स्टेटमेंट में ब्लॉक-स्कोप वाले वैरिएबल का इस्तेमाल किया जा सकता है.

इस कोड स्निपेट में दो for लूप पर ध्यान दें. एक for लूप, शुरू करने वाले वैरिएबल का एलान करने के लिए var कीवर्ड का इस्तेमाल करता है, जो संख्या 0, 1 और 2 के ज़रिए बढ़ता है. दूसरा for लूप, शुरू करने वाले वैरिएबल का एलान करने के लिए let कीवर्ड का इस्तेमाल करता है.

for (var i = 0; i < 2; i++) {
    // ...
}

console.log(i); // 2

for (let j = 0; j < 2; j++) {
    // ...
}

console.log(j); // The j variable isn't defined.

कोड के पिछले उदाहरण में, आपने देखा होगा कि पहले for लूप में i वैरिएबल, for लूप के बाहर लीक हुआ है. साथ ही, इसमें 2 वैल्यू अब भी बनी हुई है, क्योंकि var कीवर्ड, ब्लॉक करने के दायरे का इस्तेमाल नहीं करता. समस्या को दूसरे for लूप में ठीक कर दिया गया है. इसमें let कीवर्ड के साथ बताए गए j वैरिएबल के दायरे को for लूप के ब्लॉक तक सीमित कर दिया गया है और for लूप खत्म होने के बाद यह वैरिएबल मौजूद नहीं रहता.

किसी दूसरे दायरे में वैरिएबल नाम का फिर से इस्तेमाल करना

स्कोप किसी फ़ंक्शन में शामिल वैरिएबल को अलग कर सकता है. ऐसा तब भी हो सकता है, जब एक ही वैरिएबल नाम का इस्तेमाल, दूसरे स्कोप में कहीं भी किया गया हो.

इस उदाहरण में बताया गया है कि स्कोप का इस्तेमाल करके, एक ही वैरिएबल नाम को अलग-अलग फ़ंक्शन में फिर से इस्तेमाल कैसे किया जा सकता है:

function listOne() {
    let listItems = 10;
    console.log(listItems); // 10
}

function listTwo() {
   let listItems = 20;
   console.log(listItems); // 20
}

listOne();
listTwo();

listOne() और listTwo() फ़ंक्शन में listItems वैरिएबल को मनमुताबिक वैल्यू असाइन की गई हैं. इसलिए, ये वैरिएबल आपस में मैच नहीं करते.

बंद होना और लेक्सिकल स्कोप

क्लोज़र एक एनवायरमेंट फ़ंक्शन होता है, जिसमें इनर फ़ंक्शन, आउटर फ़ंक्शन के स्कोप को ऐक्सेस कर सकता है. इसे लेक्सिकल एनवायरमेंट भी कहा जाता है. इसलिए, JavaScript में, फ़ंक्शन को आउटर लेक्सिकल एनवायरमेंट का रेफ़रंस देने के लिए क्लोज़िंग का इस्तेमाल किया जाता है, जिससे कोड को फ़ंक्शन के बाहर तय किए गए फ़ंक्शन रेफ़रंस वैरिएबल के अंदर रखने की सुविधा मिलती है. असल में, बाहरी लेक्सिकल एनवायरमेंट के रेफ़रंस चेन को कोड किया जा सकता है, ताकि किसी फ़ंक्शन को किसी फ़ंक्शन से कॉल किया जा सके और उसके बाद कोई दूसरा फ़ंक्शन कॉल किया जा सके.

इस उदाहरण में, कोड लेक्सिकल एनवायरमेंट के साथ क्लोज़र फ़ॉर्म बनाता है. यह एनवायरमेंट, outer() फ़ंक्शन को शुरू करने पर बनता है. यह hello वैरिएबल के ऊपर बंद हो जाता है. इसलिए, hello वैरिएबल का इस्तेमाल setTimeout कॉलबैक फ़ंक्शन में किया जाता है.

function outer() {
    const hello = 'world';

    setTimeout(function () {
        console.log('Within the closure!', hello)
    }, 100);
}

outer();

लेक्सिकल स्कोप के साथ, स्कोप सोर्स कोड को कंपाइल करने के दौरान तय किया जाता है, न कि रनटाइम के दौरान. लेक्सिकल एनवायरमेंट के बारे में ज़्यादा जानने के लिए, लेक्सिकल स्कोपिंग और क्लोज़र पढ़ें.

मॉड्यूल

JavaScript मॉड्यूल की मदद से JavaScript कोड को व्यवस्थित किया जा सकता है. इनका सही तरीके से इस्तेमाल करने पर, ये आपके कोड बेस को बेहतर तरीके से इस्तेमाल करने में मदद करते हैं. साथ ही, कोड को दोबारा इस्तेमाल करने में भी मदद करते हैं. अलग-अलग फ़ाइलों में वैरिएबल शेयर करने के लिए ग्लोबल वैरिएबल का इस्तेमाल करने के बजाय, JavaScript मॉड्यूल वैरिएबल को एक्सपोर्ट और import करने की तकनीक उपलब्ध कराता है.

// hello.js file
function hello() {
  return 'Hello world!';
}

export { hello };

// app.js file
import { hello } from './hello.js';

console.log(hello()); // Hello world!

स्कोप विज़ुअलाइज़र का डेमो

स्कोप एक ऐसा बुनियादी सिद्धांत है जिसे हर JavaScript डेवलपर को समझना चाहिए. स्कोप सिस्टम को बेहतर ढंग से समझने के लिए, JS स्कोप विज़ुअलाइज़र की मदद से अपना कोड लिखा जा सकता है. JavaScript के स्कोप को विज़ुअलाइज़ करने में आपकी मदद करने के लिए, डेमो में कोड को कलर करने का इस्तेमाल किया गया है.

नतीजा

इस लेख में अलग-अलग तरह के स्कोप के बारे में बताया गया है. JavaScript दायरा, वेब डेवलपमेंट के सबसे बेहतर कॉन्सेप्ट में से एक है. इसलिए, आपके लिए यह बहुत अच्छी बात है कि आपने इस कॉन्टेंट को पढ़ लिया है और इस विषय को समझने के लिए समय निकाला है.

दायरा उपयोगकर्ताओं के लिए उपलब्ध सुविधा नहीं है. इससे सिर्फ़ कोड लिखने वाले वेब डेवलपर पर असर पड़ता है. हालांकि, स्कोप के काम करने के तरीके की जानकारी होने से, गड़बड़ी आने पर उसे ठीक किया जा सकता है.