यह कीवर्ड

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 ऑब्जेक्ट