this
कीवर्ड, उस ऑब्जेक्ट की वैल्यू दिखाता है जिसे फ़ंक्शन को कॉल करते समय, फ़ंक्शन से बंधा जाता है. इसका मतलब है कि किसी फ़ंक्शन को, किसी तरीके के तौर पर, स्टैंडअलोन फ़ंक्शन के तौर पर या कंस्ट्रक्टर के तौर पर कॉल करने पर, उसकी वैल्यू अलग-अलग होती है.
जब किसी फ़ंक्शन को कॉल किया जाता है, तो वह उस फ़ंक्शन वाले ऑब्जेक्ट के रेफ़रंस के तौर पर, स्क्रीन के पीछे this
कीवर्ड का एक इंस्टेंस बनाता है. साथ ही, अपने दायरे में मौजूद प्रॉपर्टी और मेथड का ऐक्सेस देता है.
this
के साथ काम करना, const
के साथ तय किए गए वैरिएबल के साथ काम करने जैसा ही है. किसी कॉन्स्टेंट की तरह, this
को हटाया नहीं जा सकता और उसकी वैल्यू को फिर से असाइन नहीं किया जा सकता. हालांकि, this
कीवर्ड में मौजूद ऑब्जेक्ट के तरीकों और प्रॉपर्टी में बदलाव किया जा सकता है.
ग्लोबल बाइंडिंग
किसी फ़ंक्शन या ऑब्जेक्ट के संदर्भ के बाहर, this
का मतलब globalThis
प्रॉपर्टी से है. यह प्रॉपर्टी, ज़्यादातर JavaScript एनवायरमेंट में ग्लोबल ऑब्जेक्ट का रेफ़रंस होती है. वेब ब्राउज़र में चल रही स्क्रिप्ट के संदर्भ में,
ग्लोबल ऑब्जेक्ट window
ऑब्जेक्ट होता है:
this;
> Window {0: Window, window: Window, self: Window, document: document, name: '', location: Location, ...}
Node.js में, globalThis
एक global
ऑब्जेक्ट है:
$ node
Welcome to Node.js v20.10.0.
Type ".help" for more information.
> this
<ref *1> Object [global] {
...
}
स्ट्रिक्ट मोड के बाहर, this
का मतलब स्टैंडअलोन फ़ंक्शन में मौजूद ग्लोबल ऑब्जेक्ट से भी है. ऐसा इसलिए है, क्योंकि पैरंट Window
वह ऑब्जेक्ट होता है जिसके पास उन फ़ंक्शन का "मालिकाना हक" होता है.
function myFunction() {
console.log( this );
}
myFunction();
> Window {...}
(function() {
console.log( this );
}());
> Window {...}
स्ट्रिक्ट मोड का इस्तेमाल करने पर, स्टैंडअलोन फ़ंक्शन में this
की वैल्यू undefined
होती है:
(function() {
"use strict";
console.log( this );
}());
> undefined
स्ट्रिक्ट मोड के आने से पहले, this
के लिए null
या undefined
वैल्यू को ग्लोबल ऑब्जेक्ट के रेफ़रंस से बदल दिया जाता था. इस लेगसी व्यवहार की वजह से, आपको कभी-कभी ग्लोबल बाइंडिंग को "डिफ़ॉल्ट बाइंडिंग" के तौर पर दिख सकता है.
इंप्लिसिट बाइंडिंग
जब किसी फ़ंक्शन को किसी ऑब्जेक्ट के मेथड के तौर पर कॉल किया जाता है, तो उस मेथड में मौजूद this
का इंस्टेंस, उस ऑब्जेक्ट को रेफ़र करता है जिसमें मेथड मौजूद होता है. साथ ही, उस ऑब्जेक्ट के साथ मौजूद मेथड और प्रॉपर्टी को ऐक्सेस करने की अनुमति देता है:
let myObject = {
myValue: "This is my string.",
myMethod() {
console.log( this.myValue );
}
};
myObject.myMethod();
> "This is my string."
ऐसा लग सकता है कि this
की वैल्यू इस बात पर निर्भर करती है कि किसी फ़ंक्शन और उसके दायरे में आने वाले ऑब्जेक्ट को कैसे तय किया गया है. इसके बजाय, this
की वैल्यू के लिए कॉन्टेक्स्ट, मौजूदा एक्सीक्यूशन कॉन्टेक्स्ट होता है. इस मामले में, एक्सीक्यूशन कॉन्टेक्स्ट यह है कि myObject
ऑब्जेक्ट, myMethod
तरीके को कॉल कर रहा है. इसलिए, myObject
, this
की वैल्यू है. पिछले उदाहरणों के हिसाब से, यह एक तकनीकी बात लग सकती है. हालांकि, this
के बेहतर इस्तेमाल के लिए, इस अंतर को ध्यान में रखना ज़रूरी है.
आम तौर पर, this
का इस्तेमाल ऐसे तरीके से करें कि आस-पास के कोड का कोई खास स्ट्रक्चर न हो. इस नियम का अपवाद, ES5 के ऐरो फ़ंक्शन हैं.
ऐरो फ़ंक्शन में this
ऐरो फ़ंक्शन में,
this
लेक्सिकल तौर पर इकट्ठा किए गए एनवायरमेंट में बाइंडिंग में बदल जाता है. इसका मतलब है कि ऐरो फ़ंक्शन में this
, उस फ़ंक्शन के सबसे नज़दीकी कॉन्टेक्स्ट में this
की वैल्यू को दिखाता है:
let myObject = {
myMethod() { console.log( this ); },
myArrowFunction: () => console.log( this ),
myEnclosingMethod: function () {
this.myArrowFunction = () => { console.log(this) };
}
};
myObject.myMethod();
> Object { myMethod: myMethod(), myArrowFunction: myArrowFunction() }
myObject.myArrowFunction();
> Window {...}
पिछले उदाहरण में, myObject.myMethod()
उस ऑब्जेक्ट के तौर पर myObject
को लॉग करता है जिसके पास उस तरीके का "मालिकाना हक" है. हालांकि, myObject.myArrowFunction()
globalThis
(या undefined
) दिखाता है, क्योंकि ऐरो फ़ंक्शन में मौजूद this
का इंस्टेंस, सबसे बड़े स्कोप को रेफ़र करता है.
इस उदाहरण में, myEnclosingMethod
उस ऑब्जेक्ट पर ऐरो फ़ंक्शन बनाता है जिसमें इसे लागू किया जाता है. ऐरो फ़ंक्शन में मौजूद this
का इंस्टेंस, अब उस एलिमेंट के अंदर मौजूद this
की वैल्यू को रेफ़र करता है जिसमें वह ऐरो फ़ंक्शन मौजूद है. myEnclosingMethod
में मौजूद this
की वैल्यू, myObject
को रेफ़र करती है. इसलिए, ऐरो फ़ंक्शन तय करने के बाद, ऐरो फ़ंक्शन में मौजूद this
भी myObject
को रेफ़र करता है:
let myObject = {
myMethod() { console.log( this ); },
myEnclosingMethod: function () {
this.myArrowFunction = () => { console.log(this) };
}
};
myObject.myEnclosingMethod();
myObject.myArrowFunction();
> Object { myMethod: myMethod(), myArrowFunction: myArrowFunction() }
एक्सप्लिसिट बाइंडिंग
this
के साथ काम करने के ज़्यादातर उदाहरणों में, इंप्लिसिट बाइंडिंग का इस्तेमाल किया जाता है. हालांकि, कभी-कभी आपको this
की वैल्यू की ज़रूरत पड़ सकती है, ताकि अनुमानित कॉन्टेक्स्ट के बजाय, खास कॉन्टेक्स्ट को लागू किया जा सके. यहां एक उदाहरण दिया गया है. यह उदाहरण setTimeout
के कॉलबैक फ़ंक्शन में this
के साथ काम कर रहा है. हालांकि, यह उदाहरण थोड़ा पुराना है, क्योंकि इस कॉलबैक का एक यूनीक एक्सीक्यूशन कॉन्टेक्स्ट है:
var myObject = {
myString: "This is my string.",
myMethod() {
console.log( this.myString );
}
};
myObject.myMethod();
> "This is my string."
setTimeout( myObject.myMethod, 100 );
> undefined
हालांकि, setTimeout
की इस खास कमी को अब दूसरी सुविधाओं की मदद से ठीक कर दिया गया है, लेकिन this
को "खोने" से जुड़ी ऐसी ही समस्याओं को पहले ठीक किया जा चुका है. इसके लिए, this
की वैल्यू का साफ़ तौर पर रेफ़रंस दिया गया था. आपको कभी-कभी, लेगसी कोडबेस में that
, self
या _this
जैसे आइडेंटिफ़ायर का इस्तेमाल करके, किसी वैरिएबल को this
असाइन किया जा सकता है. ये, वैरिएबल के लिए सामान्य आइडेंटिफ़ायर के नियम हैं. इनमें, पास की गई this
वैल्यू शामिल होती है.
call()
, bind()
या apply()
तरीकों का इस्तेमाल करके किसी फ़ंक्शन को कॉल करने पर,
this
उस ऑब्जेक्ट का साफ़ तौर पर रेफ़रंस देता है जिसे कॉल किया जा रहा है:
let myFunction = function() {
console.log( this.myValue );
}
let myObject = {
"myValue" : "This is my string."
};
myFunction.call( myObject );
> "This is my string."
var myObject = {
myString: "This is my string.",
myMethod() {
console.log( this.myString );
}
};
setTimeout( myObject.myMethod.bind( myObject ), 100 );
> "This is my string."
एक्सप्लिसिट बाइंडिंग, इंप्लिसिट बाइंडिंग से दी गई this
वैल्यू को बदल देती है.
let myObject = {
"myValue" : "This string sits alongside myMethod.",
myMethod() {
console.log( this.myValue );
}
};
let myOtherObject = {
"myValue" : "This is a string in another object entirely.",
};
myObject.myMethod.call( myOtherObject );
> "This is a string in another object entirely."
अगर किसी फ़ंक्शन को इस तरह से कॉल किया जाता है कि this
की वैल्यू को undefined
या null
पर सेट किया जा सके, तो स्ट्रिक्ट मोड के बाहर उस वैल्यू को globalThis
से बदल दिया जाता है:
let myFunction = function() {
console.log( this );
}
myFunction.call( null );
> Window {...}
इसी तरह, अगर किसी फ़ंक्शन को इस तरह से कॉल किया जाता है कि वह this
को प्राइमटिव वैल्यू दे, तो उस वैल्यू को स्ट्रिक्ट मोड के बाहर, प्राइमटिव वैल्यू के रैपर ऑब्जेक्ट से बदल दिया जाता है:
let myFunction = function() {
console.log( this );
}
let myNumber = 10;
myFunction.call( myNumber );
> Number { 10 }
स्ट्रिक्ट मोड में, पास की गई this
वैल्यू को किसी भी तरह से ऑब्जेक्ट में बदला नहीं जाता,
भले ही वह प्राइमिटिव, null
या undefined
वैल्यू हो:
"use strict";
let myFunction = function() {
console.log( this );
}
let myNumber = 10;
myFunction.call( myNumber );
> 10
myFunction.call( null );
> null
new
बाइंडिंग
जब new
कीवर्ड का इस्तेमाल करके, किसी क्लास को कंस्ट्रक्टर के तौर पर इस्तेमाल किया जाता है, तो this
से नए बनाए गए इंस्टेंस का पता चलता है:
class MyClass {
myString;
constructor() {
this.myString = "My string.";
}
logThis() {
console.log( this );
}
}
const thisClass = new MyClass();
thisClass.logThis();
> Object { myString: "My string." }
इसी तरह, new
का इस्तेमाल करके कॉल किए गए कंस्ट्रक्टर फ़ंक्शन में this
की वैल्यू, बनाए जा रहे ऑब्जेक्ट को रेफ़र करती है:
function MyFunction() {
this.myString = "My string.";
this.logThis = function() {
console.log( this );
}
}
const myObject = new MyFunction();
myObject.logThis();
> Object { myString: "My string.", logThis: logThis() }
इवेंट हैंडलर बाइंडिंग
इवेंट हैंडलर के संदर्भ में, this
की वैल्यू उस ऑब्जेक्ट का रेफ़रंस देती है जो इसे ट्रिगर करता है. इसका मतलब है कि इवेंट हैंडलर के कॉलबैक फ़ंक्शन में, this
हैंडलर से जुड़े एलिमेंट का रेफ़रंस देता है:
let button = document.querySelector( "button" );
button.addEventListener( "click", function( event ) { console.log( this ); } );
जब कोई उपयोगकर्ता पिछले स्निपेट में button
के साथ इंटरैक्ट करता है, तो नतीजा <button>
वाला एलिमेंट ऑब्जेक्ट होता है:
> Button {}
जब ऐरो फ़ंक्शन का इस्तेमाल इवेंट लिसनर कॉलबैक के तौर पर किया जाता है, तो this
की वैल्यू, सबसे नज़दीक के एक्सेक्यूशन कॉन्टेक्स्ट से फिर से दी जाती है. सबसे ऊपर के लेवल पर, इसका मतलब है कि इवेंट हैंडलर कॉलबैक फ़ंक्शन में this
, globalThis
है:
let button = document.querySelector( "button" );
button.addEventListener( "click", ( event ) => { console.log( this ); } );
> undefined
किसी भी दूसरे ऑब्जेक्ट की तरह, जब किसी इवेंट लिसनर के कॉलबैक फ़ंक्शन का रेफ़रंस देने के लिए call()
, bind()
या apply()
तरीकों का इस्तेमाल किया जाता है, तो this
ऑब्जेक्ट का साफ़ तौर पर रेफ़रंस देता है:
let button = document.querySelector( "button" );
let myObject = {
"myValue" : true
};
function handleClick() {
console.log( this );
}
button.addEventListener( "click", handleClick.bind( myObject ) );
> Object { myValue: true }
देखें कि आपको क्या समझ आया
वेब ब्राउज़र में चल रही स्क्रिप्ट के लिए, वह ग्लोबल ऑब्जेक्ट क्या है जिसका this
, किसी फ़ंक्शन या ऑब्जेक्ट के कॉन्टेक्स्ट के बाहर इस्तेमाल करने पर रेफ़र करता है?
window
ऑब्जेक्टbrowser
ऑब्जेक्टundefined
ऑब्जेक्ट