जावास्क्रिप्ट this कीवर्ड को समझना
यदि आप प्रोग्रामर बनना चाहते हैं, चाहे आप कोई भी विशिष्ट क्षेत्र चुनें, आपको लगभग निश्चित रूप से जावास्क्रिप्ट से निपटना होगा। यह विनम्र शुरुआत से एक सच्चे पावरहाउस में विकसित हुआ है। अब यह फ्रंट एंड, बैकएंड, मोबाइल, गेम्स, डेस्कटॉप ऐप्स, और यहां तक कि मशीन लर्निंग को कवर करता है!
अब, इससे पहले कि आप जावास्क्रिप्ट मास्टर बनें और शाखा लगाएं, आपको बुनियादी बातें सीखनी होंगी। this कीवर्ड शायद आपकी सीखने की सूची में नंबर एक होना चाहिए।
वास्तव में this क्या है?
सीधे शब्दों में कहें, this एक पॉइंटर है, जावास्क्रिप्ट कोड में फंक्शन या मेथड को किस ऑब्जेक्ट ने कॉल किया, इसका संदर्भ देने का एक तरीका। आम आदमी की शर्तों में, this वही है जो डॉट के बाईं ओर है।

इसके दो मुख्य उपयोग हैं। आइए कुछ उदाहरणों के साथ उनका पता लगाएं।
this के साथ ऑब्जेक्ट्स बनाना
function Book(title, author, genre) { this.title = title; this.author = author; this.genre = genre; } const book1 = new Book("Lord Of The Rings", "J.R.R. Tolkien", "Fantasy"); const book2 = new Book("Tools Of Titans", "Tim Ferriss", "Self-help"); console.log(book1); console.log(book2);
उपरोक्त कोड निम्न आउटपुट उत्पन्न करता है:

यहां, हमने एक कंस्ट्रक्टर फंक्शन परिभाषित किया जिससे हम बुक ऑब्जेक्ट्स बनाते हैं जो पैरामीटर्स के रूप में शीर्षक, लेखक, और शैली लेते हैं।
कंस्ट्रक्टर फंक्शन एक ऑब्जेक्ट "ब्लूप्रिंट" फंक्शन है जिससे हम दिए गए नाम (हमारे मामले में Book) के ऑब्जेक्ट्स बना सकते हैं।
हमने myBook नामक एक ऑब्जेक्ट बनाया, और आवश्यक पैरामीटर्स पास किए (जिन्हें फंक्शन को कॉल या इनवोक करते समय आर्ग्यूमेंट्स कहा जाता है, पैरामीटर्स के विपरीत जब हम इसे परिभाषित करते हैं)।
अंत में हमने myBook को लॉग किया, और इसके संबंधित प्रॉपर्टीज के साथ ऑब्जेक्ट वापस प्राप्त किया। इस तरह, हमारे द्वारा बनाया गया प्रत्येक नया बुक ऑब्जेक्ट पास किए गए मानों को असाइन कर दिया जाता है।
this के साथ प्रॉपर्टीज एक्सेस करना:
const girl = { name: "Sarah", age: 26, introduce() { console.log( "Hi! " + "I'm " + this.name + " and I'm " + this.age + " years old." ); }, };

यहां हमने girl नामक वेरिएबल परिभाषित किया जो name और age प्रॉपर्टीज, और introduce फंक्शन के साथ ऑब्जेक्ट रखता है।
फंक्शन ऑब्जेक्ट की प्रॉपर्टीज का उपयोग करके एक परिचयात्मक वाक्य लॉग करता है, उन्हें this.wanted_property से एक्सेस करके।
जावास्क्रिप्ट में This और स्कोप
डिफ़ॉल्ट रूप से, जब ग्लोबल स्कोप में उपयोग किया जाता है, अर्थात परिभाषित फंक्शन या ऑब्जेक्ट के अंदर नहीं, this ग्लोबल ऑब्जेक्ट को संदर्भित करेगा। ब्राउज़र में, window ग्लोबल ऑब्जेक्ट है।
जब आप जावास्क्रिप्ट में कुछ प्रिमिटिव डेटा (स्ट्रिंग्स, नंबर्स, बूलियन्स...), ऑब्जेक्ट, या फंक्शन घोषित करते हैं, तो वे सभी ग्लोबल (window) ऑब्जेक्ट से जुड़ जाते हैं।
जो कुछ भी आप "खुले में" लिखते हैं, आप उसे ऐसे पढ़ सकते हैं जैसे उसके सामने window. लिखा हो। आइए इस कोड स्निपेट पर नज़र डालें:
function returnThis() { return this; }
पहले हम returnThis नामक फंक्शन को ग्लोबल स्कोप में परिभाषित करते हैं जो this का मान लौटाता है। फिर हम इसे returnThis() लिखकर कॉल करते हैं।
चूंकि यह ग्लोबली स्कोप्ड है, हम इसे window.returnThis() के रूप में देख सकते हैं, जो हमें डॉट के बाईं ओर क्या है, यह लौटाता है।

ऑब्जेक्ट फंक्शन्स यानी मेथड्स
अब यदि हम एक नया ऑब्जेक्ट परिभाषित करते हैं जिसमें वही फंक्शन अंदर है (जिसे ऑब्जेक्ट मेथड कहा जाता है) और हम इसे एक बार फिर कॉल करते हैं, तो हमें वह ऑब्जेक्ट (कर्ली ब्रेसेस द्वारा दर्शाया गया) लौटाया जाएगा।
const object = { returnThis() { return this; }, }; object.returnThis();

this की गुत्थी और इसके तीन समाधान
यदि फंक्शन सीधे ऑब्जेक्ट से जुड़ा नहीं है, तो फंक्शन के अंदर this ग्लोबल ऑब्जेक्ट को संदर्भित करेगा।
const weirdBehaviorObject = { directlyTiedFunction() { return this; }, directlyTiedOuterFunction() { return function indirectNestedFunction() { return this; }; }, };
आइए इसे ब्राउज़र में चलाएं और देखें कि हमें क्या मिलता है:

हमने एक ऑब्जेक्ट परिभाषित किया जिसमें एक फंक्शन this फिर से लौटाता है, और दूसरा जो इनर फंक्शन लौटाता है, जो तब this लौटाता है।
जब हम indirectNestedFunction को कॉल करना चाहते हैं, तो हम पहले () एक बार लिखकर आउटर फंक्शन को कॉल करते हैं जो इनर को लौटाता है।
फिर हम इनर को दूसरे () से कॉल करते हैं जो window लौटाता है।
यह जावास्क्रिप्ट के रहस्यमय व्यवहारों में से एक है, और यह कुछ अप्रत्याशित और अवांछित आश्चर्यों को रास्ता देता है।
सौभाग्य से, इस मुद्दे को हल करने के तरीके हैं। पहला क्लोजर बनाकर है, जो प्री-ES6 में किया जाता था। दूसरा तरीका ऐरो फंक्शन्स का उपयोग करके है, और तीसरा bind मेथड का उपयोग करके है, जो call और apply मेथड्स से निकटता से संबंधित है।
#1 क्लोजर्स के साथ this हल करना
क्लोजर एक स्थायी मेमोरी स्टोर है, जिसका अर्थ है कि वेरिएबल फंक्शन समाप्त होने पर गायब नहीं होता। यह जावास्क्रिप्ट इंजन द्वारा तब बनाया जाता है जब नेस्टेड फंक्शन आउटर फंक्शन में परिभाषित वेरिएबल को संदर्भित कर रहा होता है ताकि आउटर फंक्शन समाप्त होने के बाद भी इसकी पहुंच बनी रहे। यहां हमारे this उदाहरण के साथ यह कैसा दिखता है:
const objectWithClosure = { closureFunction() { const self = this; return function enclosedFunction() { return self; }; }, };

हमने closureFunction के साथ एक ऑब्जेक्ट परिभाषित किया, जिसमें हमने self नामक वेरिएबल को हमारे this मान को स्टोर करने के लिए परिभाषित किया। चूंकि closureFunction सीधे कंटेनिंग ऑब्जेक्ट से जुड़ा हुआ है, this का मान इसे संदर्भित करता है। अब, हमारे enclosedFunction में, this आमतौर पर window ऑब्जेक्ट को संदर्भित करेगा। चूंकि हमने कंटेनिंग फंक्शन से this तक पहुंचने के लिए क्लोजर का उपयोग किया, हम कॉलिंग ऑब्जेक्ट को इसके मान के रूप में संरक्षित करने में सक्षम हैं।
#2 ऐरो फंक्शन्स के साथ this हल करना
दूसरा समाधान यकीनन ES6 के साथ आई सबसे अच्छी विशेषताओं में से एक का उपयोग कर रहा है, जो ऐरो फंक्शन्स हैं।
ऐरो फंक्शन्स फंक्शन्स लिखने के लिए अधिक संक्षिप्त सिंटैक्स दर्शाते हैं। इसके अलावा, वे this को खोजने के लिए स्कोप में एक स्तर ऊपर देखेंगे, अर्थात उस फंक्शन में जिसमें यह समाहित है।
तो यदि हम अपने ऑब्जेक्ट को इस तरह परिभाषित करते हैं:
const arrowFunctionObject = { outerFunc() { return () => this; }, };

हम देख सकते हैं कि ऐरो फंक्शन वास्तविक ऑब्जेक्ट लौटाता है, न कि window।
ऐसा इसलिए है क्योंकि इसने आउटर फंक्शन को देखा जिसने इसे कॉल किया, जहां this arrowFunctionObject को संदर्भित करता है। तो, ऐरो फंक्शन्स में एक तरह का बिल्ट-इन क्लोजर होता है।
नेस्टेड ऐरो फंक्शन्स
बेशक, यह जावास्क्रिप्ट है, तो यहां एक और गुत्थी है। यह कुछ ऐसा है जिसका सामना आप शायद तकनीकी इंटरव्यू के बाहर कभी नहीं करेंगे, लेकिन इसे जानने के लिए यह पर्याप्त कारण है।
क्या होता है यदि हम ऐरो फंक्शन को रेगुलर फंक्शन के अंदर नेस्ट करते हैं, और फिर दूसरे फंक्शन के अंदर? यह ऐसा दिखता है:
const arrowNestedInRegularFunctionObject = { outerFunction() { return function regularFunction() { return () => this; }; }, };

हमारे ऑब्जेक्ट में outerFunction है जिसे कॉल करने पर, इनर regularFunction लौटाता है।
हम फिर regularFunction को कॉल करते हैं और यह इनरमोस्ट ऐरो फंक्शन लौटाता है।
अब, इसे कॉल करने पर, यह window ऑब्जेक्ट लौटाता है।
ऐरो फंक्शन स्कोप में केवल 1 स्तर ऊपर देखेगा। चूंकि इसे समाहित करने वाला regularFunction सीधे हमारे ऑब्जेक्ट से जुड़ा नहीं है, इसलिए window के बजाय लौटाया जाता है।
यदि हम, हालांकि, ऐरो फंक्शन को ऐरो फंक्शन के अंदर नेस्ट करते हैं, जो रेगुलर फंक्शन के अंदर है, तो हमें अपेक्षित परिणाम मिलेगा, जो वास्तविक कंटेनिंग ऑब्जेक्ट है।
const nestedArrowFunctionObject = { outerFunction() { return () => { return () => this; }; }, };

इस मामले में इनर ऐरो फंक्शन आउटर की ओर देखता है। आउटर भी ऐरो फंक्शन है तो यह एक और स्तर ऊपर देखता है। रेगुलर outerFunction सीधे कॉलिंग ऑब्जेक्ट से जुड़ा हुआ है, और परिणामस्वरूप, ऑब्जेक्ट वही है जो this. के रूप में लौटाया जाता है।
#3 bind मेथड के साथ this हल करना
अंत में, तीसरा समाधान bind मेथड का उपयोग करना है। bind मेथड का उपयोग यह स्पष्ट रूप से घोषित करने के लिए किया जाता है कि this को क्या संदर्भित करना चाहिए। यह आर्ग्यूमेंट के रूप में पास किए गए ऑब्जेक्ट को प्राप्त करता है, और इसे फंक्शन के this कीवर्ड से बांधता है।
const arrowNestedInRegularFunctionObject = { outerFunction() { return function regularFunction() { return () => this; }.bind(arrowNestedInRegularFunctionObject); }, };

इस उदाहरण में, हमने bind को उस फंक्शन से चेन किया जो सामान्य रूप से this के रूप में window ऑब्जेक्ट लौटाएगा। हम इसे वह ऑब्जेक्ट पास करते हैं जिसे हम this के रूप में संदर्भित करना चाहते हैं आर्ग्यूमेंट के रूप में, और हमारी समस्या हल हो जाती है।
This उतना कठिन नहीं जब आप जावास्क्रिप्ट समझते हैं
पहले! वह काफी गहरा गोता था। अब, आप पूछ सकते हैं, this के साथ इतनी परेशानी और भ्रम क्यों?
कारण यह है कि, जावास्क्रिप्ट में बाकी सब चीजों के विपरीत, this डायनामिकली स्कोप्ड है। इसका मतलब है कि जावास्क्रिप्ट इंजन रनटाइम पर परिभाषित करता है कि this क्या दर्शाता है जब कोड एक्जीक्यूट होता है, यह देखकर कि कहां से और कौन इसे कॉल कर रहा है।
इसके विपरीत, जावास्क्रिप्ट में बाकी सब कुछ लेक्सिकली स्कोप्ड है, अर्थात इसका मान वहां परिभाषित होता है जहां वेरिएबल परिभाषित है, जब कोड लिखा जाता है।
this की बदौलत, हम एक ऑब्जेक्ट "ब्लूप्रिंट" एक बार बना सकते हैं, और डायनामिकली अलग-अलग प्रॉपर्टी मानों के साथ ऑब्जेक्ट्स बना सकते हैं जैसे हमने अपने बुक उदाहरण में देखा।
हम this.wanted_property के साथ मेथड्स भी बना सकते हैं जो ऑब्जेक्ट की प्रॉपर्टीज को उजागर और हेरफेर करते हैं।
हम जावास्क्रिप्ट की विचित्रताओं के आसपास काम कर सकते हैं, और इसके व्यवहार को आत्मविश्वास से नियंत्रित कर सकते हैं, और अपेक्षित परिणाम उत्पन्न कर सकते हैं।
अब जब आप जावास्क्रिप्ट में this को समझते हैं, साथ ही कुछ अन्य मौलिक अवधारणाओं को, आप जाकर प्रयोग कर सकते हैं, अभ्यास कर सकते हैं, और जावास्क्रिप्ट मास्टरी की ओर अधिक आत्मविश्वास से कदम बढ़ा सकते हैं।
आपके पास this है!