यह कीवर्ड

कीवर्ड 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 तरीके को कॉल कर रहा है. इसलिए, this के लिए myObject वैल्यू है. पिछले उदाहरणों के हिसाब से, यह तकनीकी जैसी लग सकती है, लेकिन 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 है (या स्ट्रिक्ट मोड में undefined):

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