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

इस लेख में, स्कोप और 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 वैरिएबल का एक ग्लोबल स्कोप है और इसे फ़ंक्शन के बाहर लिखा गया है. रन और एक्ज़ीक्यूट करने के दौरान, globalMessage वैरिएबल की वैल्यू को JavaScript प्रोग्राम में कहीं से भी ऐक्सेस किया जा सकता है.

इस कोड स्निपेट में, 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 जिसे वैरिएबल को ऐक्सेस करना हो.

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

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

इस उदाहरण में, 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 Scope जुड़ें विज़ुअलाइज़र की मदद से खुद का कोड लिखने की कोशिश करें. डेमो में, कोड में कलर का इस्तेमाल होता है, ताकि आपको JavaScript के स्कोप को विज़ुअलाइज़ करने में मदद मिल सके.

नतीजा

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

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