"यह" कीवर्ड कैसे काम करता है?


1308

मैंने देखा है कि thisस्टैक ओवरफ्लो साइट पर जावास्क्रिप्ट में उपयोग किया गया कीवर्ड क्या है और यह कैसे सही (और गलत तरीके से) है, इसका स्पष्ट विवरण नहीं दिखता है ।

मैंने इसके साथ कुछ बहुत ही अजीब व्यवहार देखा है और यह समझने में असफल रहा कि ऐसा क्यों हुआ है।

कैसे thisकाम करता है और इसका उपयोग कब किया जाना चाहिए?


6
मुझे यह तब मिला जब मैंने " goirled
वाई वोंग


2
पीटर मिचौक्स पीटर के उपयोग की वकालत करता है this ।michaux.ca
Marcel Korpel

1
MDN ओवरव्यू आधा-खराब नहीं है ... developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/…
dat

2
thisकीवर्ड की एक दिलचस्प व्याख्या : रेनसॉफ्ट .io
दिमित्री पाव्लुटिन

जवाबों:


1349

मैं पहले जावास्क्रिप्ट ( दर्पण ) में माइक वेस्ट के लेख को पढ़ने की सलाह देता हूं । यह जावास्क्रिप्ट में अवधारणाओं और गुंजाइश श्रृंखलाओं का एक उत्कृष्ट, मैत्रीपूर्ण परिचय है ।this

एक बार जब आप अभ्यस्त होने लगते हैं this, तो नियम वास्तव में बहुत सरल होते हैं। ECMAScript 5.1 स्टैंडर्ड परिभाषित करता है this:

§11.1.1this कीवर्ड

thisवर्तमान निष्पादन संदर्भ से ThisBinding के मूल्य के कीवर्ड का मूल्यांकन

यह बाइंडिंग कुछ ऐसा है जो जावास्क्रिप्ट दुभाषिया बनाए रखता है क्योंकि यह जावास्क्रिप्ट कोड का मूल्यांकन करता है, जैसे एक विशेष सीपीयू रजिस्टर जो किसी वस्तु का संदर्भ रखता है। दुभाषिया जब भी तीन अलग-अलग मामलों में से किसी एक में निष्पादन संदर्भ स्थापित करता है, तो यह थिंकिंग अपडेट करता है:

1. प्रारंभिक वैश्विक निष्पादन संदर्भ

यह जावास्क्रिप्ट कोड के लिए मामला है जो शीर्ष-स्तर पर मूल्यांकन किया जाता है, उदाहरण के लिए जब सीधे अंदर <script>:

<script>
  alert("I'm evaluated in the initial global execution context!");

  setTimeout(function () {
      alert("I'm NOT evaluated in the initial global execution context.");
  }, 1);
</script>

प्रारंभिक वैश्विक निष्पादन संदर्भ में कोड का मूल्यांकन करते समय, यह बंधन वैश्विक ऑब्जेक्ट पर सेट होता है, window( .410.4.1.1 )।

Eval कोड डालना

  • … इस eval() बाइंडिंग के सीधे कॉल से अपरिवर्तित रह जाता है; यह कॉलिंग एक्ज़ीक्यूशन संदर्भ के थाइबिन्डिंग ( .210.4.2 (2) (a)) के समान है।

  • … यदि इस प्रत्यक्ष eval()
    बंधन से कॉल नहीं होता है तो ग्लोबल ऑब्जेक्ट को वैश्विक वैश्विक निष्पादन संदर्भ ( 110.4.2 (1)) में निष्पादित करते हुए सेट किया जाता है

§15.1.2.1.1 परिभाषित करता है कि प्रत्यक्ष कॉल क्या eval()है। असल में, eval(...)एक प्रत्यक्ष कॉल है जबकि कुछ ऐसा है (0, eval)(...)या var indirectEval = eval; indirectEval(...);एक अप्रत्यक्ष कॉल है eval()। देखें chuckj का जवाब करने के लिए जावास्क्रिप्ट में eval ( 'इस') बनाम (1, eval) ( 'इस')? और दिमित्री सोशनिकोव के ईसीएमए -262-5 पर विस्तार से। अध्याय 2. सख्त मोड। जब आप एक अप्रत्यक्ष eval()कॉल का उपयोग कर सकते हैं ।

फ़ंक्शन कोड दर्ज करना

यह किसी फ़ंक्शन को कॉल करते समय होता है। यदि किसी फ़ंक्शन को किसी ऑब्जेक्ट पर, जैसे कि obj.myMethod()या समतुल्य कहा जाता है obj["myMethod"](), तो ThisBinding ऑब्जेक्ट पर सेट होता है ( objउदाहरण में; example13.2.1 )। अधिकांश अन्य मामलों में, यह बाइंडिंग वैश्विक ऑब्जेक्ट ( .310.4.3 ) पर सेट है ।

"अधिकांश अन्य मामलों में" लिखने का कारण यह है कि आठ ईसीएमएस्क्रिप्ट 5 बिल्ट-इन फ़ंक्शन हैं जो इसबाइंडिंग को तर्क सूची में निर्दिष्ट करने की अनुमति देते हैं। ये विशेष कार्य एक तथाकथित लेते हैं thisArgजो फ़ंक्शन ( .310.4.3 ) को कॉल करते समय यह थिंकिंग बन जाता है ।

ये विशेष अंतर्निहित कार्य हैं:

  • Function.prototype.apply( thisArg, argArray )
  • Function.prototype.call( thisArg [ , arg1 [ , arg2, ... ] ] )
  • Function.prototype.bind( thisArg [ , arg1 [ , arg2, ... ] ] )
  • Array.prototype.every( callbackfn [ , thisArg ] )
  • Array.prototype.some( callbackfn [ , thisArg ] )
  • Array.prototype.forEach( callbackfn [ , thisArg ] )
  • Array.prototype.map( callbackfn [ , thisArg ] )
  • Array.prototype.filter( callbackfn [ , thisArg ] )

Function.prototypeफ़ंक्शंस के मामले में , उन्हें एक फ़ंक्शन ऑब्जेक्ट पर कॉल किया जाता है, लेकिन फ़ंक्शन ऑब्जेक्ट के लिए थ्रेडबाइंडिंग सेट करने के बजाय, इस बाइंडिंग को सेट किया जाता है thisArg

Array.prototypeकार्यों के मामले में , दिए गए callbackfnको निष्पादन के संदर्भ में कहा जाता है जहां यह thisArgआपूर्ति करने के लिए सेट किया गया है ; अन्यथा, वैश्विक वस्तु के लिए।

वे सादे जावास्क्रिप्ट के लिए नियम हैं। जब आप जावास्क्रिप्ट लाइब्रेरीज़ (जैसे jQuery) का उपयोग शुरू करते हैं, तो आप पा सकते हैं कि कुछ लाइब्रेरी फ़ंक्शंस मान में हेरफेर करते हैं this। उन जावास्क्रिप्ट पुस्तकालयों के डेवलपर्स ऐसा इसलिए करते हैं क्योंकि यह सबसे आम उपयोग के मामलों का समर्थन करता है, और लाइब्रेरी के उपयोगकर्ता आमतौर पर इस व्यवहार को अधिक सुविधाजनक पाते हैं। जब thisलाइब्रेरी फ़ंक्शंस का संदर्भ देते हुए कॉलबैक फ़ंक्शंस पास करते हैं, तो आपको किसी भी गारंटी के लिए प्रलेखन का उल्लेख करना चाहिए thisकि फ़ंक्शन को कहा जाता है।

यदि आप सोच रहे हैं कि एक जावास्क्रिप्ट लाइब्रेरी किस तरह से मूल्य में हेरफेर करता है this, तो लाइब्रेरी केवल एक में निर्मित जावास्क्रिप्ट कार्यों में से एक का उपयोग करके स्वीकार कर रही है thisArg। आप भी, कॉलबैक फ़ंक्शन लेने के लिए अपना स्वयं का फ़ंक्शन लिख सकते हैं और thisArg:

function doWork(callbackfn, thisArg) {
    //...
    if (callbackfn != null) callbackfn.call(thisArg);
}

एक विशेष मामला है जिसका मैंने अभी तक उल्लेख नहीं किया है। newऑपरेटर के माध्यम से एक नई वस्तु का निर्माण करते समय , जावास्क्रिप्ट दुभाषिया एक नई, खाली वस्तु बनाता है, कुछ आंतरिक गुणों को सेट करता है, और फिर नए ऑब्जेक्ट पर कंस्ट्रक्टर फ़ंक्शन को कॉल करता है। इस प्रकार, जब एक फ़ंक्शन को एक कंस्ट्रक्टर संदर्भ में कहा जाता है, का मान thisनई वस्तु है जिसे इंटरप्रेटर बनाया जाता है:

function MyType() {
    this.someData = "a string";
}

var instance = new MyType();
// Kind of like the following, but there are more steps involved:
// var instance = {};
// MyType.call(instance);

तीर कार्य

एरो फ़ंक्शंस (ECMA6 में पेश) के दायरे को बदल देते हैं this। मौजूदा विहित प्रश्न, एरो फ़ंक्शन बनाम फ़ंक्शन घोषणा / अभिव्यक्तियाँ देखें: क्या वे समकक्ष / विनिमेय हैं? अधिक जानकारी के लिए। लेकिन संक्षेप में:

एरो फ़ंक्शंस के पास अपना नहीं है this.... बाध्यकारी। इसके बजाय, उन पहचानकर्ताओं को किसी अन्य चर की तरह शाब्दिक दायरे में हल किया जाता है। इसका मतलब है कि एक एरो फंक्शन के अंदर, this... एरो फंक्शन thisको एनवायरनमेंट के वैल्यूज में परिभाषित किया गया है।

बस मनोरंजन के लिए, कुछ उदाहरणों के साथ अपनी समझ का परीक्षण करें

उत्तरों को प्रकट करने के लिए, हल्के भूरे रंग के बक्सों पर माउस ले जाएँ।

  1. thisचिह्नित लाइन पर मूल्य क्या है ? क्यों?

    window - प्रारंभिक वैश्विक निष्पादन संदर्भ में चिह्नित रेखा का मूल्यांकन किया जाता है।

    if (true) {
        // What is `this` here?
    }
  2. निष्पादित thisहोने पर चिह्नित लाइन पर मूल्य क्या है obj.staticFunction()? क्यों?

    obj - किसी ऑब्जेक्ट पर फ़ंक्शन को कॉल करते समय, यह बाइंडिंग ऑब्जेक्ट पर सेट होता है।

    var obj = {
        someData: "a string"
    };
    
    function myFun() {
        return this // What is `this` here?
    }
    
    obj.staticFunction = myFun;
    
    console.log("this is window:", obj.staticFunction() == window);
    console.log("this is obj:", obj.staticFunction() == obj);
      

  3. thisचिह्नित लाइन पर मूल्य क्या है ? क्यों?

    window

    इस उदाहरण में, जावास्क्रिप्ट दुभाषिया फ़ंक्शन कोड में प्रवेश करता है, लेकिन क्योंकि myFun/ obj.myMethodकिसी ऑब्जेक्ट पर नहीं बुलाया जाता है, यह बाइंडिंग सेट है window

    यह पायथन से अलग है, जिसमें एक विधि ( obj.myMethod) तक पहुंच एक बाध्य विधि ऑब्जेक्ट बनाता है ।

    var obj = {
        myMethod: function () {
            return this; // What is `this` here?
        }
    };
    var myFun = obj.myMethod;
    console.log("this is window:", myFun() == window);
    console.log("this is obj:", myFun() == obj);
      

  4. thisचिह्नित लाइन पर मूल्य क्या है ? क्यों?

    window

    यह एक मुश्किल था। जब eval कोड का मूल्यांकन, thisहै obj। हालाँकि, eval कोड में, myFunकिसी ऑब्जेक्ट पर कॉल नहीं किया जाता है, इसलिए ThisBinding को windowकॉल के लिए सेट किया गया है।

    function myFun() {
        return this; // What is `this` here?
    }
    var obj = {
        myMethod: function () {
            eval("myFun()");
        }
    };
  5. thisचिह्नित लाइन पर मूल्य क्या है ? क्यों?

    obj

    लाइन myFun.call(obj);विशेष अंतर्निहित फ़ंक्शन का आह्वान कर रही है Function.prototype.call(), जो thisArgपहले तर्क के रूप में स्वीकार करता है।

    function myFun() {
        return this; // What is `this` here?
    }
    var obj = {
        someData: "a string"
    };
    console.log("this is window:", myFun.call(obj) == window);
    console.log("this is obj:", myFun.call(obj) == obj);
      


6
@ अलि: वे ECMAScript स्टैंडर्ड, ECMA-262 के संस्करण 5.1 के भीतर खंडों के संदर्भ हैं । मैं उन्हें प्रदान करता हूं ताकि आप चाहें तो तकनीकी विवरणों के लिए मानक पढ़ सकते हैं।
डैनियल ट्रेबिएन

1
मुझे लगता है कि @supertonsky # 2 के बारे में सही है - अगर myFun () को वैश्विक दायरे से बुलाया जाता है, और ऑब्जेक्ट पर एक विधि के रूप में नहीं, तो "यह" वैश्विक ऑब्जेक्ट होगा, इसलिए प्रश्न का संक्षिप्त विवरण। btw - मैं वास्तव में इस तरह से कुछ के लिए जवाब पाने के लिए माउसओवर का उपयोग करने का विचार पसंद करता हूं ।
user655489

2
लेकिन, jsfiddle.net/H4LYm/2 से पता चलता है कि setTimeoutउदाहरण में से एक thisहै window(global)
केविन मेरेडिथ

2
पायथन से आने से एक निराशा की स्तरों की कल्पना होगी जब मैं 3 उदाहरण में टकरा गया था .. smh
Marius Mucenicu

1
यह उत्तर संभवतः ES2020 वास्तविकता को प्रतिबिंबित करने के लिए अद्यतन किया जाना चाहिए, भले ही परिवर्तन केवल शब्दावली हो।
बेन एस्टन

156

thisजावास्क्रिप्ट में अलग कीवर्ड बर्ताव करता है अन्य भाषाओं की तुलना में। ऑब्जेक्ट ओरिएंटेड भाषाओं में, thisकीवर्ड क्लास के वर्तमान उदाहरण को संदर्भित करता है। जावास्क्रिप्ट thisमें फ़ंक्शन के मंगलाचरण संदर्भ ( context.function()) और जहां इसे कहा जाता है, द्वारा निर्धारित किया जाता है।

1. जब वैश्विक संदर्भ में उपयोग किया जाता है

जब आप thisवैश्विक संदर्भ में उपयोग करते हैं , तो यह वैश्विक ऑब्जेक्ट ( windowब्राउज़र में) के लिए बाध्य है

document.write(this);  //[object Window]

जब आप thisवैश्विक संदर्भ में परिभाषित फ़ंक्शन के अंदर उपयोग करते हैं , तब thisभी वैश्विक ऑब्जेक्ट के लिए बाध्य होता है क्योंकि फ़ंक्शन को वास्तव में वैश्विक संदर्भ का एक तरीका बनाया जाता है।

function f1()
{
   return this;
}
document.write(f1());  //[object Window]

ऊपर f1वैश्विक वस्तु का एक तरीका बनाया गया है। इस प्रकार हम इसे windowवस्तु के रूप में भी कह सकते हैं :

function f()
{
    return this;
}

document.write(window.f()); //[object Window]

2. जब वस्तु विधि के अंदर प्रयोग किया जाता है

जब आप thisकिसी ऑब्जेक्ट विधि के अंदर कीवर्ड का उपयोग करते हैं , तो ऑब्जेक्ट thisको "तत्काल" संलग्न करने के लिए बाध्य होता है।

var obj = {
    name: "obj",
    f: function () {
        return this + ":" + this.name;
    }
};
document.write(obj.f());  //[object Object]:obj

ऊपर मैंने डबल कोट्स में तुरंत शब्द डाला है। यह बिंदु बनाना है कि यदि आप किसी अन्य ऑब्जेक्ट के अंदर ऑब्जेक्ट को घोंसले में डालते हैं, तो thisतत्काल माता-पिता के लिए बाध्य है।

var obj = {
    name: "obj1",
    nestedobj: {
        name:"nestedobj",
        f: function () {
            return this + ":" + this.name;
        }
    }            
}

document.write(obj.nestedobj.f()); //[object Object]:nestedobj

भले ही आप फ़ंक्शन को स्पष्ट रूप से ऑब्जेक्ट के लिए एक विधि के रूप में जोड़ते हैं, यह अभी भी नियमों से ऊपर है, जो thisअभी भी तत्काल मूल ऑब्जेक्ट की ओर इशारा करता है।

var obj1 = {
    name: "obj1",
}

function returnName() {
    return this + ":" + this.name;
}

obj1.f = returnName; //add method to object
document.write(obj1.f()); //[object Object]:obj1

3. जब संदर्भ-कम फ़ंक्शन को लागू करना

जब आप thisकिसी भी संदर्भ (यानी किसी वस्तु पर नहीं) के बिना लागू किए गए फ़ंक्शन के अंदर का उपयोग करते हैं , तो यह वैश्विक ऑब्जेक्ट ( windowब्राउज़र में) के लिए बाध्य है (भले ही फ़ंक्शन ऑब्जेक्ट के अंदर परिभाषित हो)।

var context = "global";

var obj = {  
    context: "object",
    method: function () {                  
        function f() {
            var context = "function";
            return this + ":" +this.context; 
        };
        return f(); //invoked without context
    }
};

document.write(obj.method()); //[object Window]:global 

सभी कार्यों के साथ यह कोशिश कर रहा है

हम कार्यों के साथ भी उपरोक्त बिंदुओं को आजमा सकते हैं। हालाँकि कुछ अंतर हैं।

  • ऊपर हमने ऑब्जेक्ट शाब्दिक संकेतन का उपयोग करके वस्तुओं में सदस्यों को जोड़ा। हम उपयोग करके कार्यों में सदस्यों को जोड़ सकते हैं this। उन्हें निर्दिष्ट करने के लिए।
  • ऑब्जेक्ट शाब्दिक अंकन वस्तु का एक उदाहरण बनाता है जिसे हम तुरंत उपयोग कर सकते हैं। फ़ंक्शन के साथ हमें पहले newऑपरेटर का उपयोग करके इसकी आवृत्ति बनाने की आवश्यकता हो सकती है ।
  • ऑब्जेक्ट शाब्दिक दृष्टिकोण में भी, हम डॉट ऑपरेटर का उपयोग करके स्पष्ट रूप से पहले से परिभाषित ऑब्जेक्ट में सदस्यों को जोड़ सकते हैं। यह केवल विशिष्ट उदाहरण में जोड़ा जाता है। हालाँकि मैंने फ़ंक्शन प्रोटोटाइप में चर जोड़ा है ताकि यह फ़ंक्शन के सभी उदाहरणों में परिलक्षित हो।

नीचे मैंने उन सभी चीजों को आज़माया जो हमने ऑब्जेक्ट और thisऊपर के साथ किया था , लेकिन पहले सीधे ऑब्जेक्ट लिखने के बजाय फ़ंक्शन बनाकर।

/********************************************************************* 
  1. When you add variable to the function using this keyword, it 
     gets added to the function prototype, thus allowing all function 
     instances to have their own copy of the variables added.
*********************************************************************/
function functionDef()
{
    this.name = "ObjDefinition";
    this.getName = function(){                
        return this+":"+this.name;
    }
}        

obj1 = new functionDef();
document.write(obj1.getName() + "<br />"); //[object Object]:ObjDefinition   

/********************************************************************* 
   2. Members explicitly added to the function protorype also behave 
      as above: all function instances have their own copy of the 
      variable added.
*********************************************************************/
functionDef.prototype.version = 1;
functionDef.prototype.getVersion = function(){
    return "v"+this.version; //see how this.version refers to the
                             //version variable added through 
                             //prototype
}
document.write(obj1.getVersion() + "<br />"); //v1

/********************************************************************* 
   3. Illustrating that the function variables added by both above 
      ways have their own copies across function instances
*********************************************************************/
functionDef.prototype.incrementVersion = function(){
    this.version = this.version + 1;
}
var obj2 = new functionDef();
document.write(obj2.getVersion() + "<br />"); //v1

obj2.incrementVersion();      //incrementing version in obj2
                              //does not affect obj1 version

document.write(obj2.getVersion() + "<br />"); //v2
document.write(obj1.getVersion() + "<br />"); //v1

/********************************************************************* 
   4. `this` keyword refers to the immediate parent object. If you 
       nest the object through function prototype, then `this` inside 
       object refers to the nested object not the function instance
*********************************************************************/
functionDef.prototype.nestedObj = { name: 'nestedObj', 
                                    getName1 : function(){
                                        return this+":"+this.name;
                                    }                            
                                  };

document.write(obj2.nestedObj.getName1() + "<br />"); //[object Object]:nestedObj

/********************************************************************* 
   5. If the method is on an object's prototype chain, `this` refers 
      to the object the method was called on, as if the method was on 
      the object.
*********************************************************************/
var ProtoObj = { fun: function () { return this.a } };
var obj3 = Object.create(ProtoObj); //creating an object setting ProtoObj
                                    //as its prototype
obj3.a = 999;                       //adding instance member to obj3
document.write(obj3.fun()+"<br />");//999
                                    //calling obj3.fun() makes 
                                    //ProtoObj.fun() to access obj3.a as 
                                    //if fun() is defined on obj3

4. जब कंस्ट्रक्टर फ़ंक्शन के अंदर उपयोग किया जाता है

जब फ़ंक्शन का उपयोग एक कंस्ट्रक्टर के रूप में किया जाता है (अर्थात जब इसे newकीवर्ड के साथ कहा जाता है ), तो thisफ़ंक्शन बॉडी के अंदर नई ऑब्जेक्ट का निर्माण किया जा रहा है।

var myname = "global context";
function SimpleFun()
{
    this.myname = "simple function";
}

var obj1 = new SimpleFun(); //adds myname to obj1
//1. `new` causes `this` inside the SimpleFun() to point to the
//   object being constructed thus adding any member
//   created inside SimipleFun() using this.membername to the
//   object being constructed
//2. And by default `new` makes function to return newly 
//   constructed object if no explicit return value is specified

document.write(obj1.myname); //simple function

5. जब प्रोटोटाइप चेन पर परिभाषित फ़ंक्शन के अंदर उपयोग किया जाता है

यदि विधि किसी ऑब्जेक्ट की प्रोटोटाइप श्रृंखला पर है, तो thisइस तरह की विधि ऑब्जेक्ट को संदर्भित करती है विधि को बुलाया गया था, जैसे कि विधि को ऑब्जेक्ट पर परिभाषित किया गया है।

var ProtoObj = {
    fun: function () {
        return this.a;
    }
};
//Object.create() creates object with ProtoObj as its
//prototype and assigns it to obj3, thus making fun() 
//to be the method on its prototype chain

var obj3 = Object.create(ProtoObj);
obj3.a = 999;
document.write(obj3.fun()); //999

//Notice that fun() is defined on obj3's prototype but 
//`this.a` inside fun() retrieves obj3.a   

6. इनसाइड कॉल (), लागू () और बाइंड () फ़ंक्शन

  • इन सभी तरीकों पर परिभाषित किया गया है Function.prototype
  • ये विधियां एक बार एक फ़ंक्शन लिखने और इसे अलग-अलग संदर्भ में लागू करने की अनुमति देती हैं। दूसरे शब्दों में, वे उस मूल्य को निर्दिष्ट करने की अनुमति देते हैं thisजिसका उपयोग तब किया जाएगा जब फ़ंक्शन निष्पादित किया जा रहा हो। मूल फ़ंक्शन को लागू करने के लिए वे किसी भी पैरामीटर को लेते हैं जब इसे लागू किया जाता है।
  • fun.apply(obj1 [, argsArray])अंदर obj1के मूल्य के रूप में सेट करता thisहै fun()और इसके तर्क fun()के argsArrayरूप में गुजर तत्वों को बुलाता है।
  • fun.call(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])- अंदर obj1के मूल्य के रूप में सेट करता thisहै fun()और इसके तर्कों के रूप में fun()गुजरता arg1, arg2, arg3, ...है।
  • fun.bind(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])- फन के संदर्भ में दिए गए फन के संदर्भ में और निर्दिष्ट मापदंडों के लिए बाध्य के मापदंडों के funसाथ रिटर्न देता है ।thisobj1funarg1, arg2, arg3,...
  • अब के बीच का अंतर apply, callऔर bindस्पष्ट हो गया होगा। applyसरणी-समान ऑब्जेक्ट के रूप में कार्य करने के लिए तर्कों को निर्दिष्ट करने की अनुमति देता है अर्थात एक संख्यात्मक lengthसंपत्ति और इसी गैर-नकारात्मक पूर्णांक गुणों के साथ एक वस्तु । जबकि callसीधे फ़ंक्शन के तर्कों को निर्दिष्ट करने की अनुमति देता है। दोनों applyऔर callतुरंत निर्दिष्ट संदर्भ में और निर्दिष्ट तर्क के साथ समारोह का आह्वान। दूसरी ओर, bindकेवल निर्दिष्ट thisमान और तर्कों से बंधे कार्य को लौटाता है। हम इस लौटे फ़ंक्शन को संदर्भ को एक चर में निर्दिष्ट करके कैप्चर कर सकते हैं और बाद में हम इसे किसी भी समय कॉल कर सकते हैं।
function add(inc1, inc2)
{
    return this.a + inc1 + inc2;
}

var o = { a : 4 };
document.write(add.call(o, 5, 6)+"<br />"); //15
      //above add.call(o,5,6) sets `this` inside
      //add() to `o` and calls add() resulting:
      // this.a + inc1 + inc2 = 
      // `o.a` i.e. 4 + 5 + 6 = 15
document.write(add.apply(o, [5, 6]) + "<br />"); //15
      // `o.a` i.e. 4 + 5 + 6 = 15

var g = add.bind(o, 5, 6);       //g: `o.a` i.e. 4 + 5 + 6
document.write(g()+"<br />");    //15

var h = add.bind(o, 5);          //h: `o.a` i.e. 4 + 5 + ?
document.write(h(6) + "<br />"); //15
      // 4 + 5 + 6 = 15
document.write(h() + "<br />");  //NaN
      //no parameter is passed to h()
      //thus inc2 inside add() is `undefined`
      //4 + 5 + undefined = NaN</code>

7. thisघटना संचालकों के अंदर

  • जब आप किसी तत्व के ईवेंट हैंडलर्स को सीधे फ़ंक्शन असाइन करते हैं, तो thisसीधे ईवेंट हैंडलिंग फ़ंक्शन के अंदर का उपयोग संबंधित तत्व को संदर्भित करता है। इस तरह के प्रत्यक्ष कार्य असाइनमेंट को addeventListenerविधि का उपयोग करके या पारंपरिक ईवेंट पंजीकरण विधियों जैसे के माध्यम से किया जा सकता है onclick
  • इसी तरह, जब आप तत्व thisकी घटना संपत्ति (जैसे <button onclick="...this..." >) के अंदर सीधे उपयोग करते हैं , तो यह तत्व को संदर्भित करता है।
  • हालाँकि thisईवेंट हैंडलिंग फ़ंक्शन या ईवेंट प्रॉपर्टी के अंदर कहे जाने वाले अन्य फ़ंक्शन के माध्यम से अप्रत्यक्ष रूप से उपयोग वैश्विक ऑब्जेक्ट के लिए हल होता है window
  • जब हम Microsoft के इवेंट पंजीकरण मॉडल विधि का उपयोग करके फ़ंक्शन हैंडलर को फ़ंक्शन से जोड़ते हैं, तो उपरोक्त व्यवहार को प्राप्त किया जाता है attachEvent। इवेंट हैंडलर को फ़ंक्शन असाइन करने के बजाय (और इस प्रकार तत्व की फ़ंक्शन विधि), यह फ़ंक्शन को ईवेंट पर कॉल करता है (प्रभावी रूप से इसे वैश्विक संदर्भ में कॉल करता है)।

मैं JSFiddle में बेहतर प्रयास करने की सलाह देता हूं

<script> 
    function clickedMe() {
       alert(this + " : " + this.tagName + " : " + this.id);
    } 
    document.getElementById("button1").addEventListener("click", clickedMe, false);
    document.getElementById("button2").onclick = clickedMe;
    document.getElementById("button5").attachEvent('onclick', clickedMe);   
</script>

<h3>Using `this` "directly" inside event handler or event property</h3>
<button id="button1">click() "assigned" using addEventListner() </button><br />
<button id="button2">click() "assigned" using click() </button><br />
<button id="button3" onclick="alert(this+ ' : ' + this.tagName + ' : ' + this.id);">used `this` directly in click event property</button>

<h3>Using `this` "indirectly" inside event handler or event property</h3>
<button onclick="alert((function(){return this + ' : ' + this.tagName + ' : ' + this.id;})());">`this` used indirectly, inside function <br /> defined & called inside event property</button><br />

<button id="button4" onclick="clickedMe()">`this` used indirectly, inside function <br /> called inside event property</button> <br />

IE only: <button id="button5">click() "attached" using attachEvent() </button>

8. thisES6 एरो फंक्शन में

एक तीर फ़ंक्शन में, thisसामान्य चर की तरह व्यवहार करेंगे: यह अपने शाब्दिक दायरे से विरासत में मिलेगा। फ़ंक्शन का this, जहां एरो फ़ंक्शन परिभाषित किया गया है, एरो फ़ंक्शन होगा this

तो, यह वही व्यवहार है:

(function(){}).bind(this)

निम्नलिखित कोड देखें:

const globalArrowFunction = () => {
  return this;
};

console.log(globalArrowFunction()); //window

const contextObject = {
  method1: () => {return this},
  method2: function(){
    return () => {return this};
  }
};

console.log(contextObject.method1()); //window

const contextLessFunction = contextObject.method1;

console.log(contextLessFunction()); //window

console.log(contextObject.method2()()) //contextObject

const innerArrowFunction = contextObject.method2();

console.log(innerArrowFunction()); //contextObject 

"जब आप वैश्विक संदर्भ में परिभाषित फ़ंक्शन के अंदर इसका उपयोग करते हैं, तो यह अभी भी वैश्विक ऑब्जेक्ट के लिए बाध्य है क्योंकि फ़ंक्शन वास्तव में वैश्विक संदर्भ का एक तरीका है।" गलत है। यह किसी फ़ंक्शन को कॉल करने या बाइंड करने के तरीके से निर्धारित होता है, न कि जहां इसे परिभाषित किया गया है। एक आधार संदर्भ ( "संदर्भ") के बिना किसी भी समारोह कॉलिंग लागू हो जाएगी इस वैश्विक वस्तु के लिए या कठोर मोड में अपरिभाषित रहते हैं।
RobG

@RobG हम्म हो सकता है, लेकिन मैंने एमडीएन पर यह पाया : इस मामले में, thisकॉल द्वारा मूल्य निर्धारित नहीं किया गया है। चूंकि कोड सख्त मोड में नहीं है, इसलिए मान का thisहमेशा एक ऑब्जेक्ट होना चाहिए , इसलिए यह वैश्विक ऑब्जेक्ट के लिए डिफ़ॉल्ट है। और वास्तव में यही कारण है कि मुझे लगा कि हम सीधे कॉल कर सकते हैं window.f1(), इसलिए इसका मतलब f1()पहले ही windowऑब्जेक्ट से जुड़ा हुआ है , मेरा मतलब है कि आह्वान से पहले। क्या मैं गलत हो रहा हूँ?
महेश999

मैं "शायद फ़ंक्शन को वैश्विक संदर्भ का एक तरीका बनाया गया है" के साथ इसे लिंक करने पर आपके लिंकिंग पर (शायद स्पष्ट रूप से नहीं) टिप्पणी कर रहा था , जैसे कि यह कहा जाता है window.fn, जो यह नहीं है। यह वैश्विक ऑब्जेक्ट के लिए चूक है क्योंकि कॉल में कोई आधार संदर्भ का उपयोग नहीं किया गया था, न कि जहां फ़ंक्शन को परिभाषित किया गया है (इसलिए यह अभी भी निर्धारित किया जाता है कि फ़ंक्शन कैसे कहा गया था)। आप स्पष्ट रूप से का उपयोग कर इसे कहते हैं window.fn, तो आप सेट कर रहे हैं इस के लिए खिड़की । समान परिणाम, इसके बारे में जाने का अलग तरीका। :-)
रोबग

"ऊपर मैंने तत्काल शब्द डाल दिया है ..." नहीं, आपने नहीं किया। क्या आप कृपया इसे संशोधित कर सकते हैं ताकि त्रुटि ठीक हो जाए? यह उत्तर के लिए अर्थ लगता है और इस प्रकार मैं तब तक पढ़ना जारी नहीं रख सकता जब तक कि कुछ गलत सीखने के डर के लिए त्रुटि ठीक न हो जाए।
14

@TylerH अपने ब्राउज़र में इस पेज पर Ctrl + F करते हैं ताकि स्ट्रिंग "तत्काल" (डबल कोट्स सहित) मुझे लगता है कि अगर मुझे गलत समझ में आ रहा है तो यह है
Mahesha999

64

जावास्क्रिप्ट का this

सरल समारोह आह्वान

निम्नलिखित कार्य पर विचार करें:

function foo() {
    console.log("bar");
    console.log(this);
}
foo(); // calling the function

ध्यान दें कि हम इसे सामान्य मोड में चला रहे हैं, अर्थात सख्त मोड का उपयोग नहीं किया जाता है।

किसी ब्राउज़र में चलने पर, मान को thisलॉग इन किया जाएगा window। ऐसा इसलिए है क्योंकि windowवेब ब्राउज़र के दायरे में वैश्विक चर है।

यदि आप नोड के समान वातावरण में इस तरह के कोड को चलाते हैं। तो, thisआपके ऐप में वैश्विक चर को संदर्भित करेगा।

अब यदि हम "use strict";फ़ंक्शन घोषणा की शुरुआत में बयान जोड़कर इसे सख्त मोड में चलाते हैं , thisतो अब यह पर्यावरण के किसी भी क्षेत्र में वैश्विक चर को संदर्भित नहीं करेगा। यह सख्त मोड में भ्रम से बचने के लिए किया जाता है। thisइस मामले में, बस लॉग इन करें undefined, क्योंकि यही वह है, यह परिभाषित नहीं है।

निम्नलिखित मामलों में, हम देखेंगे कि मूल्य में हेरफेर कैसे किया जाता है this

किसी वस्तु पर कार्य करना

ऐसा करने के लिए अलग-अलग तरीके हैं। यदि आपने जावास्क्रिप्ट में मूल तरीकों को बुलाया है जैसे forEachऔर slice, आपको पहले से ही पता होना चाहिए कि thisउस मामले में चर उस Objectपर संदर्भित होता है, जिस पर आपने उस फ़ंक्शन को नोट किया है (नोट करें कि जावास्क्रिप्ट में, बस के बारे में सब कुछ एस और एस Objectसहित )। उदाहरण के लिए निम्न कोड लें।ArrayFunction

var myObj = {key: "Obj"};
myObj.logThis = function () {
    // I am a method
    console.log(this);
}
myObj.logThis(); // myObj is logged

यदि किसी Objectसंपत्ति में कोई संपत्ति होती है Function, तो वह संपत्ति एक विधि कहलाती है। यह विधि, जब कहा जाता है, तो इसके पास हमेशा वह thisपरिवर्तनशील सेट होता है जो Objectइसके साथ जुड़ा होता है। यह सख्त और गैर-सख्त दोनों तरीकों के लिए सही है।

ध्यान दें कि यदि कोई विधि किसी अन्य चर में संग्रहीत (या बल्कि, प्रतिलिपि बनाई गई) है, तो संदर्भ thisअब नए चर में संरक्षित नहीं है। उदाहरण के लिए:

// continuing with the previous code snippet

var myVar = myObj.logThis;
myVar();
// logs either of window/global/undefined based on mode of operation

अधिक सामान्यतः व्यावहारिक परिदृश्य को ध्यान में रखते हुए:

var el = document.getElementById('idOfEl');
el.addEventListener('click', function() { console.log(this) });
// the function called by addEventListener contains this as the reference to the element
// so clicking on our element would log that element itself

newकीवर्ड

जावास्क्रिप्ट में एक निर्माण कार्य पर विचार करें:

function Person (name) {
    this.name = name;
    this.sayHello = function () {
        console.log ("Hello", this);
    }
}

var awal = new Person("Awal");
awal.sayHello();
// In `awal.sayHello`, `this` contains the reference to the variable `awal`

यह कैसे काम करता है? खैर, देखते हैं कि जब हम newकीवर्ड का उपयोग करते हैं तो क्या होता है ।

  1. newकीवर्ड के साथ फ़ंक्शन को कॉल करना तुरंत एक Objectप्रकार का प्रारंभ करेगा Person
  2. इसके निर्माण के लिए Objectइसके निर्माता ने निर्धारित किया है Person। इसके अलावा, ध्यान दें कि केवल typeof awalवापस आ जाएगा Object
  3. इस नए Objectको का प्रोटोटाइप सौंपा जाएगा Person.prototype। इसका मतलब यह है कि Personप्रोटोटाइप में कोई भी तरीका या संपत्ति सभी उदाहरणों के लिए उपलब्ध होगी Person, जिसमें शामिल हैं awal
  4. फ़ंक्शन Personको अब लागू किया गया है; thisनवनिर्मित वस्तु का संदर्भ होना awal

बहुत सीधा, एह?

ध्यान दें कि आधिकारिक ECMAScript कल्पना कहीं नहीं बताती है कि इस प्रकार के कार्य वास्तविक constructorकार्य हैं। वे केवल सामान्य कार्य हैं, और newकिसी भी फ़ंक्शन पर उपयोग किए जा सकते हैं। यह सिर्फ इतना है कि हम उन्हें इस तरह से उपयोग करते हैं, और इसलिए हम उन्हें केवल ऐसे ही कहते हैं।

कार्यों पर कॉलिंग कार्य: callऔरapply

तो हाँ, चूँकि functions Objects(जावास्क्रिप्ट में वास्तव में प्रथम श्रेणी के चर भी हैं), यहाँ तक कि फ़ंक्शन के भी तरीके हैं ... अच्छी तरह से, स्वयं कार्य करते हैं।

सभी कार्यों वैश्विक से विरासत Function, और इसके कई तरीकों में से दो हैं callऔर applyहै, और दोनों के मूल्य में हेरफेर करने के लिए इस्तेमाल किया जा सकता thisसमारोह, जिस पर वे कहा जाता है में।

function foo () { console.log (this, arguments); }
var thisArg = {myObj: "is cool"};
foo.call(thisArg, 1, 2, 3);

यह उपयोग करने का एक विशिष्ट उदाहरण है call। यह मूल रूप से पहले पैरामीटर लेता है और thisफ़ंक्शन fooमें एक संदर्भ के रूप में सेट होता है thisArg। अन्य सभी मापदंडों को तर्क के रूप callमें कार्य fooमें पारित किया जाता है।
तो उपरोक्त कोड {myObj: "is cool"}, [1, 2, 3]कंसोल में लॉग इन होगा । thisकिसी भी फ़ंक्शन के मूल्य को बदलने के लिए बहुत अच्छा तरीका है ।

applyयह लगभग समान है कि callस्वीकार करें कि यह केवल दो पैरामीटर लेता है: thisArgऔर एक सरणी जिसमें फ़ंक्शन को पारित करने के लिए तर्क शामिल हैं। तो उपरोक्त callकॉल का अनुवाद applyइस तरह किया जा सकता है :

foo.apply(thisArg, [1,2,3])

ध्यान दें कि callऔर applyका मान ओवरराइड कर सकते हैं thisडॉट विधि मंगलाचरण हम दूसरी गोली में चर्चा से सेट। काफी सरल :)

पेश है…। bind!

bindके एक भाई है callऔर apply। यह Functionजावास्क्रिप्ट में वैश्विक निर्माता से सभी कार्यों द्वारा विरासत में मिली विधि भी है । के बीच का अंतर bindऔर call/ applyदोनों कि है callऔर applyवास्तव में समारोह लागू करेगा। bindदूसरी ओर, के साथ एक नया फ़ंक्शन thisArgऔर argumentsपूर्व सेट। आइए इसे बेहतर ढंग से समझने के लिए एक उदाहरण लेते हैं:

function foo (a, b) {
    console.log (this, arguments);
}
var thisArg = {myObj: "even more cool now"};
var bound = foo.bind(thisArg, 1, 2);
console.log (typeof bound); // logs `function`
console.log (bound);
/* logs `function () { native code }` */

bound(); // calling the function returned by `.bind`
// logs `{myObj: "even more cool now"}, [1, 2]`

तीनों में अंतर देखें? यह सूक्ष्म है, लेकिन उनका उपयोग अलग-अलग तरीके से किया जाता है। जैसा callऔर apply, bindभी के मूल्य में अधिक-से सवारी करेंगे thisडॉट विधि मंगलाचरण से सेट।

यह भी ध्यान दें कि इन तीन कार्यों में से कोई भी मूल कार्य में कोई बदलाव नहीं करता है। callऔर applyनए सिरे से निर्मित कार्यों से मूल्य लौटाएगा, जबकि नए सिरे से निर्मित कार्य bindको वापस करेगा, जिसे कॉल किया जाएगा।

अतिरिक्त सामान, इसे कॉपी करें

कभी-कभी, आप इस तथ्य को पसंद नहीं करते हैं कि thisगुंजाइश के साथ बदलता है, विशेष रूप से नेस्टेड गुंजाइश। निम्नलिखित उदाहरण पर एक नज़र डालें।

var myObj = {
    hello: function () {
        return "world"
        },
    myMethod: function () {
        // copy this, variable names are case-sensitive
        var that = this;
        // callbacks ftw \o/
        foo.bar("args", function () {
            // I want to call `hello` here
            this.hello(); // error
            // but `this` references to `foo` damn!
            // oh wait we have a backup \o/
            that.hello(); // "world"
        });
    }
  };

उपरोक्त कोड में, हम देखते हैं कि thisनेस्टेड स्कोप के साथ मूल्य बदल गया है, लेकिन हम thisमूल स्कोप से मान चाहते थे । इसलिए हमने कॉपी की जगह 'कॉपी' thisकी thatऔर उसका इस्तेमाल किया this। चतुर, एह?

सूचकांक:

  1. thisडिफ़ॉल्ट रूप से क्या आयोजित किया जाता है?
  2. क्या होगा यदि हम फ़ंक्शन को ऑब्जेक्ट-डॉट नोटेशन के साथ एक विधि के रूप में कहते हैं?
  3. यदि हम newकीवर्ड का उपयोग करते हैं तो क्या होगा ?
  4. हम कैसे और के thisसाथ हेरफेर करते हैं ?callapply
  5. का उपयोग कर bind
  6. thisनेस्टेड-गुंजाइश मुद्दों को हल करने के लिए नकल ।

47

"यह" सभी गुंजाइश के बारे में है। प्रत्येक फ़ंक्शन का अपना दायरा होता है, और जेएस में सब कुछ एक वस्तु है, यहां तक ​​कि एक फ़ंक्शन भी "यह" का उपयोग करके कुछ मूल्यों को स्वयं में संग्रहीत कर सकता है। OOP 101 सिखाता है कि "यह" केवल उदाहरणों पर लागू होता है एक वस्तु के पर । इसलिए, हर बार जब कोई फ़ंक्शन निष्पादित होता है, तो उस फ़ंक्शन का एक नया "उदाहरण" "इस" का एक नया अर्थ होता है।

ज्यादातर लोग भ्रमित हो जाते हैं जब वे गुमनाम बंद कार्यों के अंदर "इस" का उपयोग करने की कोशिश करते हैं:

(फ़ंक्शन (मान) {
    this.value = value;
    $ ( '। कुछ-तत्व')। प्रत्येक (समारोह (ईएलटी) {
        elt.innerHTML = this.value; // उह ओह!! संभवतः अपरिभाषित
    });
}) (2);

तो यहाँ, प्रत्येक के अंदर (), "यह" उस "मूल्य" को नहीं रखता है जिसकी आप उससे (से) उम्मीद करते हैं

this.value = value;
इसके ऊपर)। तो, इस (कोई दंडित इरादा नहीं) समस्या को खत्म करने के लिए, एक डेवलपर:

(फ़ंक्शन (मान) {
    var स्व = यह; // छोटा सा बदलाव
    self.value = value;
    $ ( '। कुछ-तत्व')। प्रत्येक (समारोह (ईएलटी) {
        elt.innerHTML = self.value; // पापा !! == २
    });
}) (2);

कोशिश करके देखो; आप प्रोग्रामिंग के इस पैटर्न को पसंद करना शुरू करेंगे


6
"जेएस में सब कुछ एक वस्तु है" सच नहीं है, जावास्क्रिप्ट में भी आदिम मूल्य हैं, देखें bclary.com/2004/11/07/#a-4.3.2
मार्सेल कोर्पल

6
आदिम मान अपने आप में कुछ विधियाँ हैं, जैसे String # substring (), संख्या # toString (), आदि। इसलिए, शायद उस लेख के समान नामकरण के साथ नहीं, वे वास्तव में ऐसा व्यवहार करते हैं मानो वे वस्तुएं हैं (वे सभी प्रोटोटाइप, यानी। स्ट्रिंग # सबस्ट्रिंग () वास्तव में है: String.prototyp.substring = function () {...})। कृपया मुझे सुधारें अगर मैं गलत हूं।
अरुणजीतसिंह

12
thisकीवर्ड गुंजाइश के साथ कोई संबंध नहीं है। इसके अलावा, यह उन कार्यों में भी एक अर्थ है जो वस्तुओं के गुण नहीं हैं।
बरगी

1
@ अरुणजीतसिंह — उस पर विचार के दो स्कूल हैं। मुझे वह पसंद है जो कहता है " सब कुछ एक वस्तु है, लेकिन कुछ को सुविधा के लिए आदिम द्वारा दर्शाया जा सकता है "। ;-)
रॉब जे

9
thisगुंजाइश के बारे में सब नहीं है। यह निष्पादन के संदर्भ के बारे में सब है, जो गुंजाइश के रूप में एक ही बात नहीं है। जावास्क्रिप्ट को शाब्दिक रूप से स्कूप किया गया है (मतलब गुंजाइश कोड के स्थान द्वारा निर्धारित की जाती है), लेकिन thisयह निर्धारित किया जाता है कि यह किस प्रकार से युक्त है जो कि आरेखित किया गया है - वह फ़ंक्शन जहां नहीं है।
स्कॉट मार्कस 5

16

चूंकि यह धागा टकरा गया है, इसलिए मैंने पाठकों के लिए नए thisविषय के लिए कुछ बिंदुओं को संकलित किया है ।

कैसे thisनिर्धारित होता है मूल्य ?

हम इस तरह का उपयोग करते हैं जैसे हम अंग्रेजी में प्राकृतिक भाषाओं में सर्वनाम का उपयोग करते हैं: "जॉन तेजी से भाग रहा है क्योंकि वह ट्रेन पकड़ने की कोशिश कर रहा है।" इसके बजाय हम लिख सकते थे “… जॉन ट्रेन पकड़ने की कोशिश कर रहा है”।

var person = {    
    firstName: "Penelope",
    lastName: "Barrymore",
    fullName: function () {

    // We use "this" just as in the sentence above:
       console.log(this.firstName + " " + this.lastName);

    // We could have also written:
       console.log(person.firstName + " " + person.lastName);
    }
}

this किसी मान को तब तक असाइन नहीं किया जाता है जब तक कि कोई ऑब्जेक्ट उस फ़ंक्शन को आमंत्रित नहीं करता है जहां इसे परिभाषित किया गया है। वैश्विक दायरे में, सभी वैश्विक चर और कार्यों को windowऑब्जेक्ट पर परिभाषित किया जाता है। इसलिए, thisएक वैश्विक फ़ंक्शन में वैश्विक windowऑब्जेक्ट को संदर्भित करता है (और इसका मूल्य है) ।

जब use strict, thisवैश्विक और अनाम कार्यों में, जो किसी भी वस्तु के लिए बाध्य नहीं हैं, का मूल्य होता है undefined

thisकीवर्ड है सबसे गलत समझा 1) हम एक विधि है कि का उपयोग करता है उधार: जब this, 2) हम एक विधि है कि का उपयोग करता है आवंटित thisएक चर करने के लिए, 3) एक समारोह है कि का उपयोग करता है thisएक कॉलबैक समारोह के रूप में 4 पारित हो जाता है, और) thisको बंद करने के अंदर प्रयोग किया जाता है - एक आंतरिक कार्य। (2)

तालिका

क्या भविष्य रखता है

ECMA स्क्रिप्ट 6 में परिभाषित , एरो-फ़ंक्शंस thisएन्कोडिंग (फ़ंक्शन या ग्लोबल) स्कोप से बाइंडिंग को अपनाते हैं ।

function foo() {
     // return an arrow function
     return (a) => {
     // `this` here is lexically inherited from `foo()`
     console.log(this.a);
  };
}
var obj1 = { a: 2 };
var obj2 = { a: 3 };

var bar = foo.call(obj1);
bar.call( obj2 ); // 2, not 3!

हालांकि तीर-फ़ंक्शंस का उपयोग करने का एक विकल्प प्रदान करता है bind(), यह ध्यान रखना महत्वपूर्ण है कि वे अनिवार्य रूप से पारंपरिक thisतंत्र को अधिक व्यापक रूप से समझने वाले लेक्सिकल स्कूपिंग के पक्ष में अक्षम कर रहे हैं । (1)


संदर्भ:

  1. इस और वस्तु प्रोटोटाइप , काइल सिम्पसन द्वारा। © 2014 Getify सॉल्यूशंस।
  2. javascriptissexy.com - http://goo.gl/pvl0GX
  3. एंगस क्रॉल - http://goo.gl/Z2RacU

16

thisजावास्क्रिप्ट में हमेशा उस फ़ंक्शन के 'स्वामी' को संदर्भित करता है जिसे निष्पादित किया जा रहा है

यदि कोई स्पष्ट स्वामी परिभाषित नहीं किया गया है, तो शीर्ष अधिकांश स्वामी, विंडो ऑब्जेक्ट, संदर्भित है।

तो अगर मैंने किया

function someKindOfFunction() {
   this.style = 'foo';
}

element.onclick = someKindOfFunction;

thisतत्व वस्तु को संदर्भित करेगा। लेकिन सावधान रहें, बहुत सारे लोग यह गलती करते हैं।

<element onclick="someKindOfFunction()">

उत्तरार्द्ध मामले में, आप केवल फ़ंक्शन को संदर्भित करते हैं, इसे तत्व को नहीं सौंपते हैं। इसलिए, thisविंडो ऑब्जेक्ट को संदर्भित करेगा।


15

जावास्क्रिप्ट में प्रत्येक निष्पादन संदर्भ में इस पैरामीटर को सेट किया गया है:

  1. फ़ंक्शन को कैसे कहा जाता है (ऑब्जेक्ट विधि के रूप में, कॉल का उपयोग करें और लागू करें, नए का उपयोग करें )
  2. बाँध का उपयोग
  3. Lexically तीर कार्यों के लिए (वे अपनाने इस उनके बाहरी निष्पादन संदर्भ से)
  4. चाहे कोड सख्त या गैर-सख्त मोड में हो
  5. क्या कोड का उपयोग करके लागू किया गया था eval

आप इस का उपयोग करके func.call, func.applyया का मान सेट कर सकते हैं func.bind

डिफ़ॉल्ट रूप से, और अधिकांश शुरुआती को क्या भ्रमित करता है, जब किसी ईवेंट को DOM तत्व पर उठाए जाने के बाद एक श्रोता को बुलाया जाता है, तो फ़ंक्शन का यह मान DOM तत्व है।

jQuery jQuery.proxy के साथ बदलने के लिए इस तुच्छ बनाता है।


9
यह कहना थोड़ा अधिक सही है कि प्रत्येक फ़ंक्शन कॉल में एक गुंजाइश है। दूसरे शब्दों में, thisजावास्क्रिप्ट के बारे में जो भ्रामक है वह यह है कि यह फ़ंक्शन की आंतरिक संपत्ति नहीं है, बल्कि फ़ंक्शन को लागू करने के तरीके की एक कलाकृति है।
पॉइन्टी

@ पॉइंट थैंक्स js में इस बारे में सबसे अधिक भ्रम का कारण क्या है, यह तथ्य यह है कि पहले इस्तेमाल की गई सभी भाषाओं में (c #, c ++), - इसे हेरफेर नहीं किया जा सकता है n हमेशा ऑब्जेक्ट उदाहरण पर इंगित करता है जबकि js में यह निर्भर करता है और जब इनवॉइस को बदला जा सकता है कार्यों का उपयोग करना func.call, func.bindआदि - सुशील
सुशील

2
thisफ़ंक्शन का दायरा संदर्भित नहीं करता है । thisएक विशिष्ट वस्तु (या संभवतः undefined) को संदर्भित करेगा , जैसा कि आपने कहा है कि इसका उपयोग करके बदला जा सकता है .call()या .apply()। एक फ़ंक्शन का दायरा (अनिवार्य रूप से, जब सरलीकृत किया जाता है) यह किस चर पर पहुंचता है, और यह पूरी तरह से इस बात पर निर्भर करता है कि फ़ंक्शन कहां घोषित किया गया है और इसे बदला नहीं जा सकता है।
nnnnnn

@ संकेत: "यह कहना थोड़ा अधिक सही है कि प्रत्येक फ़ंक्शन कॉल में एक गुंजाइश है।" यह कहने के लिए और भी सही है कि फ़ंक्शन (और अब ब्लॉक) में गुंजाइश है , फ़ंक्शन कॉल का संदर्भ है । स्कोप परिभाषित करता है कि पहचानकर्ता क्या हैं जो उस दायरे में कोड द्वारा उपयोग किए जा सकते हैं। प्रसंग परिभाषित करता है कि वे कौन से पहचानकर्ता हैं।
टीजे क्राउडर

1
"जो कुछ भी गुंजाइश है," यह "द्वारा संदर्भित है।" नहीं, thisऔर गुंजाइश कुछ भी नहीं है जो ES5 और उससे पहले एक दूसरे के साथ क्या करना है (उदाहरण के लिए, जब यह उत्तर लिखा गया था)। ES2015 (उर्फ ES6) में, thisऔर स्कोप एक न्यूनतम न्यूनतम तरीके से संबंधित हैं, जो कि एरो एरो फ़ंक्शंस ( thisएक एरो फंक्शन में इसके एन्कोडिंग स्कोप से विरासत में मिला है), लेकिन thisकभी भी स्कोप को संदर्भित नहीं करता है।
टीजे क्राउडर

10

यहाँ का एक अच्छा स्रोत thisहै JavaScript

यहाँ सारांश है:

  • यह वैश्विक है

    एक ब्राउज़र में, वैश्विक क्षेत्र में, thisहै windowवस्तु

    <script type="text/javascript">
      console.log(this === window); // true
      var foo = "bar";
      console.log(this.foo); // "bar"
      console.log(window.foo); // "bar"

    उत्तर nodeका उपयोग करने में, thisशीर्ष नाम स्थान है। आप इसे इस रूप में संदर्भित कर सकते हैं global

    >this
      { ArrayBuffer: [Function: ArrayBuffer],
        Int8Array: { [Function: Int8Array] BYTES_PER_ELEMENT: 1 },
        Uint8Array: { [Function: Uint8Array] BYTES_PER_ELEMENT: 1 },
        ...
    >global === this
     true

    में nodeएक स्क्रिप्ट से क्रियान्वित करने, thisवैश्विक क्षेत्र में एक खाली वस्तु के रूप में शुरू होता है। यह वैसा नहीं हैglobal

    \\test.js
    console.log(this);  \\ {}
    console.log(this === global); \\ fasle
  • यह कार्य करें

DOM ईवेंट हैंडलर के मामले में या जब thisArg(प्रदान किया गया है और नीचे देखें) को छोड़कर , नोड और दोनों thisमें एक फ़ंक्शन का उपयोग करने वाले ब्राउज़र में जिसे newवैश्विक गुंजाइश के संदर्भ में नहीं कहा जाता है ...

<script type="text/javascript">
    foo = "bar";

    function testThis() {
      this.foo = "foo";
    }

    console.log(this.foo); //logs "bar"
    testThis();
    console.log(this.foo); //logs "foo"
</script>

यदि आप उपयोग करते हैं use strict;, तो किस मामले में thisहोगाundefined

<script type="text/javascript">
    foo = "bar";

    function testThis() {
      "use strict";
      this.foo = "foo";
    }

    console.log(this.foo); //logs "bar"
    testThis();  //Uncaught TypeError: Cannot set property 'foo' of undefined 
</script>

यदि आप किसी फ़ंक्शन newको thisवसीयत के साथ एक नया संदर्भ कहते हैं, तो यह वैश्विक संदर्भ नहीं होगा this

<script type="text/javascript">
    foo = "bar";

    function testThis() {
      this.foo = "foo";
    }

    console.log(this.foo); //logs "bar"
    new testThis();
    console.log(this.foo); //logs "bar"

    console.log(new testThis().foo); //logs "foo"
</script>
  • यह प्रोटोटाइप

आपके द्वारा बनाए गए फ़ंक्शन फ़ंक्शन ऑब्जेक्ट बन जाते हैं। वे स्वचालित रूप से एक विशेष prototypeसंपत्ति प्राप्त करते हैं, जो कुछ ऐसा है जिसे आप मान निर्दिष्ट कर सकते हैं। जब आप अपने फ़ंक्शन को कॉल करके एक उदाहरण बनाते हैं, तो आप newउन मूल्यों तक पहुंच प्राप्त करते हैं जिन्हें आपने prototypeसंपत्ति को सौंपा है । आप उन मूल्यों का उपयोग करते हैं this

function Thing() {
  console.log(this.foo);
}

Thing.prototype.foo = "bar";

var thing = new Thing(); //logs "bar"
console.log(thing.foo);  //logs "bar"

यह आमतौर पर आवंटित करने के लिए एक गलती है सरणियों या वस्तुओं पर prototype। यदि आप चाहते हैं कि प्रत्येक के पास अपनी स्वयं की सरणियाँ हों, तो उन्हें फ़ंक्शन में बनाएँ, न कि प्रोटोटाइप में।

function Thing() {
    this.things = [];
}

var thing1 = new Thing();
var thing2 = new Thing();
thing1.things.push("foo");
console.log(thing1.things); //logs ["foo"]
console.log(thing2.things); //logs []
  • इस पर आपत्ति करें

आप thisकिसी भी फ़ंक्शन में ऑब्जेक्ट पर अन्य गुणों को संदर्भित करने के लिए उपयोग कर सकते हैं । यह एक उदाहरण के साथ बनाई गई के समान नहीं है new

var obj = {
    foo: "bar",
    logFoo: function () {
        console.log(this.foo);
    }
};

obj.logFoo(); //logs "bar"
  • DOM ईवेंट

HTML DOM ईवेंट हैंडलर में, thisहमेशा DOM एलीमेंट का संदर्भ होता है, जिसमें ईवेंट अटैच किया गया था

function Listener() {
    document.getElementById("foo").addEventListener("click",
       this.handleClick);
}
Listener.prototype.handleClick = function (event) {
    console.log(this); //logs "<div id="foo"></div>"
}

var listener = new Listener();
document.getElementById("foo").click();

जब तक आप bindसंदर्भ

function Listener() {
    document.getElementById("foo").addEventListener("click", 
        this.handleClick.bind(this));
}
Listener.prototype.handleClick = function (event) {
    console.log(this); //logs Listener {handleClick: function}
}

var listener = new Listener();
document.getElementById("foo").click();
  • यह HTML

HTML विशेषताओं के अंदर जिसमें आप जावास्क्रिप्ट डाल सकते हैं, thisतत्व का एक संदर्भ है।

<div id="foo" onclick="console.log(this);"></div>
<script type="text/javascript">
document.getElementById("foo").click(); //logs <div id="foo"...
</script>
  • यह स्पष्ट करें

आप उपयोग evalकरने के लिए उपयोग कर सकते हैं this

function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    eval("console.log(this.foo)"); //logs "bar"
}

var thing = new Thing();
thing.logFoo();
  • इसके साथ

आप स्पष्ट रूप से संदर्भित किए बिना मूल्यों को पढ़ने और लिखने के लिए वर्तमान दायरे में withजोड़ने के thisलिए उपयोग कर सकते हैं ।thisthis

function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    with (this) {
        console.log(foo);
        foo = "foo";
    }
}

var thing = new Thing();
thing.logFoo(); // logs "bar"
console.log(thing.foo); // logs "foo"
  • jQuery इस

jQuery के कई स्थानों में thisDOM तत्व का उल्लेख होगा।

<div class="foo bar1"></div>
<div class="foo bar2"></div>
<script type="text/javascript">
$(".foo").each(function () {
    console.log(this); //logs <div class="foo...
});
$(".foo").on("click", function () {
    console.log(this); //logs <div class="foo...
});
$(".foo").each(function () {
    this.click();
});
</script>

9

डैनियल, भयानक विवरण! इस पर शब्दों की एक जोड़ी और thisघटना संचालकों के मामले में निष्पादन संदर्भ सूचक की अच्छी सूची ।

दो शब्दों में, thisजावास्क्रिप्ट में उस वस्तु को इंगित किया गया है जिससे (या जिसके निष्पादन संदर्भ से) वर्तमान फ़ंक्शन चलाया गया था और यह हमेशा केवल-पढ़ने के लिए है, आप इसे वैसे भी सेट नहीं कर सकते हैं (ऐसा प्रयास 'अमान्य बाएं हाथ से समाप्त होगा' असाइनमेंट के संदेश में पक्ष।

ईवेंट हैंडलर के लिए: इनलाइन ईवेंट हैंडलर, जैसे <element onclick="foo">, पहले और पहले संलग्न किसी अन्य हैंडलर को ओवरराइड करते हैं, इसलिए सावधान रहें और इनलाइन इवेंट डेलिगेशन से दूर रहना बेहतर है। और ज़ारा अलावेर्डन का धन्यवाद जिन्होंने मुझे एक असंतोषपूर्ण बहस के माध्यम से उदाहरणों की इस सूची के लिए प्रेरित किया :)

  • el.onclick = foo; // in the foo - obj
  • el.onclick = function () {this.style.color = '#fff';} // obj
  • el.onclick = function() {doSomething();} // In the doSomething - Window
  • el.addEventListener('click',foo,false) // in the foo - obj
  • el.attachEvent('onclick, function () { // this }') // window, all the compliance to IE :)
  • <button onclick="this.style.color = '#fff';"> // obj
  • <button onclick="foo"> // In the foo - window, but you can <button onclick="foo(this)">

9

जावास्क्रिप्ट में "इस" कीवर्ड की व्याख्या कैसे की जाती है, इस बारे में बहुत भ्रम है। उम्मीद है कि यह लेख उन सभी को एक बार और आराम करने के लिए रखेगा। और भी काफी। कृपया पूरा लेख ध्यान से पढ़ें। इस लेख को लंबा है कि forewarned हो।

जिस संदर्भ में इसका उपयोग किया जाता है, उसके बावजूद, "यह" हमेशा जावास्क्रिप्ट में "वर्तमान वस्तु" का संदर्भ देता है। हालांकि, संदर्भ के अनुसार "वर्तमान वस्तु" क्या अलग हैसंदर्भ वास्तव में हो सकता है 6 में से 1 निम्नलिखित:

  1. ग्लोबल (यानी सभी कार्यों के बाहर)
  2. डायरेक्ट "नॉन बाउंड फंक्शन" कॉल के अंदर (अर्थात एक फ़ंक्शन जिसे कॉल फ़ंक्शन द्वारा बाध्य नहीं किया गया है। Name.bind )
  3. इनडायरेक्ट "नॉन बाउंड फंक्शन" के अंदर functionName.call और functionName.apply के माध्यम से कॉल करें
  4. "बाउंड फंक्शन" कॉल के अंदर (अर्थात एक फ़ंक्शन जिसे कॉल फ़ंक्शन द्वारा बाध्य किया गया है। Name.bind )
  5. जबकि वस्तु निर्माण "नए" के माध्यम से
  6. इनलाइन डोम इवेंट हैंडलर के अंदर

निम्नलिखित एक-एक करके इस संदर्भ का वर्णन करता है:

  1. वैश्विक संदर्भ (यानी सभी कार्यों के बाहर):

    सभी कार्यों के बाहर (यानी वैश्विक संदर्भ में) "वर्तमान वस्तु" (और इसलिए "इस" का मूल्य ) हमेशा ब्राउज़रों के लिए "विंडो" ऑब्जेक्ट है।

  2. डायरेक्ट "नॉन बाउंड फंक्शन" कॉल :

    डायरेक्ट "नॉन बाउंड फंक्शन" कॉल के अंदर, फ़ंक्शन कॉल को लागू करने वाली वस्तु "वर्तमान वस्तु" बन जाती है (और इसलिए "यह" का मूल्य )। यदि किसी फ़ंक्शन को स्पष्ट वर्तमान ऑब्जेक्ट के बिना कहा जाता है , तो वर्तमान ऑब्जेक्ट या तो "विंडो" ऑब्जेक्ट (नॉन स्ट्रिक्ट मोड) या अपरिभाषित (फॉर स्ट्रिक्ट मोड) है। Global Context में परिभाषित कोई भी फ़ंक्शन (या वैरिएबल) स्वचालित रूप से "विंडो" ऑब्जेक्ट का गुण बन जाता है। उदाहरण के लिए मान लीजिए कि फ़ंक्शन ग्लोबल संदर्भ में परिभाषित किया गया है

    function UserDefinedFunction(){
        alert(this)
        }

    यह विंडो ऑब्जेक्ट की संपत्ति बन जाता है, जैसे कि आपने इसे परिभाषित किया है

    window.UserDefinedFunction=function(){
      alert(this)
    }  

    "गैर सख्त मोड" में, कॉलिंग / सीधे के माध्यम से इस समारोह लागू "() UserDefinedFunction" स्वचालित रूप से / यह आह्वान के रूप में कॉल करेंगे "window.UserDefinedFunction ()" बनाने "विंडो" के रूप में "वर्तमान वस्तु" (और इसलिए का मूल्य " यह " ) " UserDefinedFunction "के भीतर है। इस फ़ंक्शन को" नॉन स्ट्रिक्ट मोड "में प्राप्त करने के बाद निम्नलिखित परिणाम प्राप्त होंगे।

    UserDefinedFunction() // displays [object Window]  as it automatically gets invoked as window.UserDefinedFunction()

    "सख्त मोड", कॉलिंग / सीधे के माध्यम से समारोह लागू में "UserDefinedFunction ()" होगा "नहीं" स्वचालित रूप से / यह आह्वान के रूप में फोन "window.UserDefinedFunction ()" .Hence "वर्तमान वस्तु" (और का मान "इस" ) के भीतर "UserDefinedFunction" किया जाएगा अपरिभाषित । इस फ़ंक्शन को "स्ट्रिक्ट मोड" में शामिल करने के परिणामस्वरूप निम्नलिखित होगा

    UserDefinedFunction() // displays undefined

    हालाँकि, विंडो ऑब्जेक्ट का उपयोग करके इसे स्पष्ट रूप से लागू करना निम्न में परिणाम होगा

    window.UserDefinedFunction() // "always displays [object Window]   irrespective of mode."

    आइए हम एक और उदाहरण देखें। कृपया निम्नलिखित कोड देखें

     function UserDefinedFunction()
        {
            alert(this.a + ","  + this.b + ","  + this.c  + ","  + this.d)
        }
    
    var o1={
                a:1,
                b:2,
                f:UserDefinedFunction
          }
    var o2={
                c:3,
                d:4,
                f:UserDefinedFunction
           }
    
    o1.f() // Shall display 1,2,undefined,undefined
    o2.f() // Shall display undefined,undefined,3,4

    उपरोक्त उदाहरण में हम देखते हैं कि जब "UserDefinedFunction" को o1 के माध्यम से लागू किया गया था , तो "यह" O1 का मूल्य लेता है और इसके गुणों का मान "a" और "b" प्रदर्शित होता है। "सी" और "डी" के मूल्य को अपरिभाषित दिखाया गया था क्योंकि ओ 1 इन गुणों को परिभाषित नहीं करता है

    इसी तरह जब "यूजरडिफाइंड फंक्शन" को ओ 2 के माध्यम से लागू किया गया था , "यह" ओ 2 का मूल्य लेता है और इसके गुणों का मूल्य "सी" और "डी" मिलता है। "ए" और "बी" के मूल्य को ओ 2 के रूप में अपरिभाषित दिखाया गया है। इन गुणों को परिभाषित नहीं करते।

  3. अप्रत्यक्ष "नॉन बाउंड फंक्शन" के अंदर functionName.call और functionName.apply के माध्यम से कॉल करें :

    जब एक "नॉन बाउंड फंक्शन" functionName.call या functionName.apply के माध्यम से कहा जाता है , तो "वर्तमान वस्तु" (और इसलिए "यह" का मूल्य) "इस" पैरामीटर (पहला पैरामीटर) के मान पर सेट है जिसे कॉल करने के लिए पारित किया गया है / आवेदन करें । निम्न कोड समान प्रदर्शित करता है।

    function UserDefinedFunction()
    {
        alert(this.a + ","  + this.b + ","  + this.c  + ","  + this.d)
    }
    var o1={
                a:1,
                b:2,
                f:UserDefinedFunction
           }
    var o2={
                c:3,
                d:4,
                f:UserDefinedFunction
           }
    
    UserDefinedFunction.call(o1) // Shall display 1,2,undefined,undefined
    UserDefinedFunction.apply(o1) // Shall display 1,2,undefined,undefined
    
    UserDefinedFunction.call(o2) // Shall display undefined,undefined,3,4
    UserDefinedFunction.apply(o2) // Shall display undefined,undefined,3,4
    
    o1.f.call(o2) // Shall display undefined,undefined,3,4
    o1.f.apply(o2) // Shall display undefined,undefined,3,4
    
    o2.f.call(o1) // Shall display 1,2,undefined,undefined
    o2.f.apply(o1) // Shall display 1,2,undefined,undefined

    उपरोक्त कोड स्पष्ट रूप से दिखाता है कि किसी भी "एनओएन बाउंड फंक्शन" के लिए "यह" मूल्य कॉल / आवेदन के माध्यम से बदला जा सकता है । इसके अलावा, यदि "इस" पैरामीटर को स्पष्ट रूप से कॉल / लागू करने के लिए पारित नहीं किया जाता है , तो "वर्तमान वस्तु" (और इसलिए "यह" का मूल्य) गैर-सख्त मोड में "विंडो" और "अपरिभाषित" को सख्त मोड में सेट किया गया है।

  4. "बाउंड फंक्शन" कॉल के अंदर (अर्थात एक फ़ंक्शन जिसे कॉल फ़ंक्शन द्वारा बाध्य किया गया है Name.bind ):

    एक बाउंड फ़ंक्शन एक फ़ंक्शन है जिसका "यह" मूल्य तय किया गया है। निम्नलिखित कोड यह दर्शाता है कि बाध्य फ़ंक्शन के मामले में "यह" कैसे काम करता है

    function UserDefinedFunction()
    {
        alert(this.a + ","  + this.b + ","  + this.c  + ","  + this.d)
    }
    var o1={
              a:1,
              b:2,
              f:UserDefinedFunction,
              bf:null
           }
    var o2={
               c:3,
               d:4,
               f:UserDefinedFunction,
               bf:null
            }
    
    var bound1=UserDefinedFunction.bind(o1); // permanantly fixes "this" value of function "bound1" to Object o1
    bound1() // Shall display 1,2,undefined,undefined
    
    var bound2=UserDefinedFunction.bind(o2); // permanantly fixes "this" value of function "bound2" to Object o2
    bound2() // Shall display undefined,undefined,3,4
    
    var bound3=o1.f.bind(o2); // permanantly fixes "this" value of function "bound3" to Object o2
    bound3() // Shall display undefined,undefined,3,4
    
    var bound4=o2.f.bind(o1); // permanantly fixes "this" value of function "bound4" to Object o1
    bound4() // Shall display 1,2,undefined,undefined
    
    o1.bf=UserDefinedFunction.bind(o2) // permanantly fixes "this" value of function "o1.bf" to Object o2
    o1.bf() // Shall display undefined,undefined,3,4
    
    o2.bf=UserDefinedFunction.bind(o1) // permanantly fixes "this" value of function "o2.bf" to Object o1
    o2.bf() // Shall display 1,2,undefined,undefined
    
    bound1.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function
    
    bound1.apply(o2) // Shall still display 1,2,undefined,undefined. "apply" cannot alter the value of "this" for bound function
    
    o2.bf.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function
    o2.bf.apply(o2) // Shall still display 1,2,undefined,undefined."apply" cannot alter the value of "this" for bound function

    जैसा कि ऊपर दिए गए कोड में दिया गया है, किसी भी "बाउंड फंक्शन" के लिए यह "मूल्य" कॉल / आवेदन के माध्यम से नहीं बदला जा सकता है । इसके अलावा, अगर "इस" पैरामीटर को स्पष्ट रूप से बाँधने के लिए पारित नहीं किया गया है, तो "वर्तमान वस्तु" (और इसलिए "इस" का मूल्य ) "विंडो" को गैर सख्त मोड में और "अपरिभाषित" को सख्त मोड में सेट किया गया है। एक और चीज़। पहले से ही बंधे फ़ंक्शन को बांधने से "यह" का मान नहीं बदलता है । यह पहले बाइंड फ़ंक्शन द्वारा निर्धारित मान के रूप में सेट रहता है।

  5. जबकि वस्तु निर्माण "नया" के माध्यम से :

    एक निर्माता फ़ंक्शन के अंदर, "वर्तमान ऑब्जेक्ट" (और इसलिए "इस" का मूल्य ) उस ऑब्जेक्ट को संदर्भित करता है जो वर्तमान में फ़ंक्शन की बाइंड स्थिति के बावजूद "नया" के माध्यम से बनाया जा रहा है। हालाँकि, अगर कंस्ट्रक्टर एक बाध्य फ़ंक्शन है, तो इसे बाध्य फ़ंक्शन के लिए निर्धारित तर्कों के पूर्वनिर्धारित सेट के साथ कहा जाएगा।

  6. इनलाइन डोम इवेंट हैंडलर के अंदर :

    कृपया निम्नलिखित HTML स्निपेट देखें

    <button onclick='this.style.color=white'>Hello World</button>
    <div style='width:100px;height:100px;' onclick='OnDivClick(event,this)'>Hello World</div>

    "इस" में उपरोक्त उदाहरण क्रमशः "बटन" तत्व और "div" तत्व का संदर्भ लें।

    पहले उदाहरण में, बटन का फ़ॉन्ट रंग सफ़ेद होने पर सेट किया जाएगा।

    दूसरे उदाहरण में जब "div" तत्व को क्लिक किया जाता है, तो वह OnDivClick फ़ंक्शन को उसके दूसरे पैरामीटर के साथ क्लिक किए गए div तत्व को संदर्भित करेगा। हालाँकि ऑनडिवक्लिक क्लिक के भीतर "यह" का मूल्य क्लिक किए गए div तत्व का संदर्भ नहीं देता है । इसे "विंडो ऑब्जेक्ट" या "अपरिभाषित" के रूप में क्रमशः गैर सख्त और सख्त मोड में सेट किया जाएगा (यदि ऑनडिवक्लिक एक अनबाउंड फ़ंक्शन है ) या पूर्वनिर्धारित मान पर सेट करें (यदि ऑनडिवक्लिक एक बाध्य फ़ंक्शन है )

निम्नलिखित पूरे लेख को सारांशित करता है

  1. वैश्विक संदर्भ में "यह" हमेशा "विंडो" ऑब्जेक्ट को संदर्भित करता है

  2. जब भी किसी कार्य का आह्वान किया जाता है, तो उसे किसी वस्तु ( "वर्तमान वस्तु" ) के संदर्भ में आमंत्रित किया जाता है । यदि वर्तमान वस्तु को स्पष्ट रूप से नहीं दी गई है, वर्तमान वस्तु है "खिड़की वस्तु" में गैर सख्त मोड और "अपरिभाषित" डिफ़ॉल्ट रूप से कठोर मोड में।

  3. एक गैर बाउंड फंक्शन के भीतर "इस" का मान उस ऑब्जेक्ट के संदर्भ में है जिसके संदर्भ में फ़ंक्शन इंविक्ड किया गया है ( "वर्तमान ऑब्जेक्ट" )

  4. एक गैर बाउंड फ़ंक्शन के भीतर "यह" का मान फ़ंक्शन के तरीकों को कॉल और लागू करने से अधिक हो सकता है।

  5. "यह" का मान एक बाउंड फ़ंक्शन के लिए तय किया गया है और फ़ंक्शन के तरीकों को कॉल और लागू करने से अधिक नहीं हो सकता है ।

  6. बंधन और पहले से ही बाध्य फ़ंक्शन "यह" के मूल्य को नहीं बदलता है। यह पहले बाइंड फ़ंक्शन द्वारा निर्धारित मान के रूप में सेट रहता है।

  7. एक निर्माता के भीतर "यह" का मूल्य वह वस्तु है जिसे बनाया और आरम्भ किया जा रहा है

  8. इनलाइन DOM ईवेंट हैंडलर के भीतर "इस" का मान उस तत्व का संदर्भ है जिसके लिए ईवेंट हैंडलर दिया गया है।


9

संभवतः सबसे विस्तृत और व्यापक लेख thisनिम्नलिखित है:

जावास्क्रिप्ट में 'यह' कीवर्ड की कोमल व्याख्या

पीछे विचार thisयह समझना है कि फ़ंक्शन इनवोकेशन प्रकारों का thisमूल्य निर्धारण पर महत्वपूर्ण महत्व है ।


परेशानियों की पहचान करते समयthis , खुद से पूछें:

कहाँ से thisलिया गया है ?

लेकिन है अपने आप से पूछना:

फ़ंक्शन को कैसे लागू किया जाता है ?

एक तीर समारोह (संदर्भ पारदर्शिता का विशेष मामला) के लिए खुद से पूछें:

thisतीर फ़ंक्शन को परिभाषित करने का क्या मूल्य है ?

इससे निपटने के दौरान यह मानसिकता सही है thisऔर आपको सिरदर्द से बचाएगा।


अपने ब्लॉग को लिंक करने के अलावा, हो सकता है कि आप इस सवाल को समझने में मदद करें कि कोई thisकीवर्ड को समझने में कैसे मदद करता है ?
मैग्नस लिंड ऑक्सलुंड

7

: यह सबसे अच्छा विवरण मैंने देखा है है JavaScripts समझे इस स्पष्टता के साथ

इस संदर्भ हमेशा के लिए संदर्भित करता है (और का मान रखती है), हालांकि यह वैश्विक क्षेत्र में एक समारोह के बाहर किया जा सकता है एक वस्तु एक विलक्षण वस्तु और यह आमतौर पर एक समारोह या एक विधि के अंदर किया जाता है। ध्यान दें कि जब हम सख्त मोड का उपयोग करते हैं, तो यह वैश्विक कार्यों और अपरिहार्य कार्यों में अपरिभाषित का मूल्य रखता है जो किसी भी वस्तु के लिए बाध्य नहीं हैं।

चार परिदृश्य हैं जहां यह भ्रमित हो सकता है:

  1. जब हम कॉलबैक फ़ंक्शन के रूप में उपयोग किए जाने वाले तर्क के रूप में एक विधि (जो इस का उपयोग करता है ) पास करते हैं।
  2. जब हम एक आंतरिक कार्य (एक बंद) का उपयोग करते हैं। यह ध्यान दें कि बंद बाहरी समारोह के उपयोग नहीं कर सकते रखना महत्वपूर्ण है यह इस कीवर्ड का उपयोग करके चर क्योंकि इस चर केवल समारोह अपने आप में पहुँचा जा सकता है, आंतरिक कार्यों के द्वारा नहीं।
  3. जब एक विधि जो इस पर निर्भर होती है, उसे संदर्भों में एक चर को सौंपा जाता है, तो इस स्थिति में मूल रूप से इच्छित वस्तु की तुलना में दूसरी वस्तु का संदर्भ दिया जाता है।
  4. का उपयोग करते समय इस बाँध के साथ-साथ लागू होते हैं, और कॉल तरीके।

वह कोड उदाहरण, स्पष्टीकरण और समाधान देता है, जो मुझे लगा कि बहुत उपयोगी था।


6

छद्मशास्त्रीय शब्दों में, जिस तरह से कई व्याख्यान 'इस' कीवर्ड को पढ़ाते हैं, एक वर्ग या ऑब्जेक्ट कंस्ट्रक्टर द्वारा त्वरित वस्तु के रूप में है। हर बार एक नई वस्तु का निर्माण एक वर्ग से किया जाता है, कल्पना करें कि हुड के तहत एक 'इस' वस्तु का एक स्थानीय उदाहरण बनाया और वापस किया जाता है। मुझे याद है यह इस तरह से पढ़ाया जाता है:

function Car(make, model, year) {
var this = {}; // under the hood, so to speak
this.make = make;
this.model = model;
this.year = year;
return this; // under the hood
}

var mycar = new Car('Eagle', 'Talon TSi', 1993);
// ========= under the hood
var this = {};
this.make = 'Eagle';
this.model = 'Talon TSi';
this.year = 1993;
return this;

5

thisजावास्क्रिप्ट में गलतफहमी अवधारणा में से एक है क्योंकि यह जगह से जगह पर थोड़ा अलग व्यवहार करता है। बस, उस फ़ंक्शनthis के "मालिक" को संदर्भित करता है जिसे हम वर्तमान में निष्पादित कर रहे हैं

thisवर्तमान वस्तु (उर्फ निष्पादन संदर्भ) के साथ काम करने में मदद करता है। यदि आप समझते हैं कि वर्तमान फ़ंक्शन किस ऑब्जेक्ट में निष्पादित हो रहा है, तो आप आसानी से समझ सकते हैं कि वर्तमान क्या thisहै

var val = "window.val"

var obj = {
    val: "obj.val",
    innerMethod: function () {
        var val = "obj.val.inner",
            func = function () {
                var self = this;
                return self.val;
            };

        return func;
    },
    outerMethod: function(){
        return this.val;
    }
};

//This actually gets executed inside window object 
console.log(obj.innerMethod()()); //returns window.val

//Breakdown in to 2 lines explains this in detail
var _inn = obj.innerMethod();
console.log(_inn()); //returns window.val

console.log(obj.outerMethod()); //returns obj.val

ऊपर हम एक ही नाम 'वैल' के साथ 3 चर बनाते हैं। एक वैश्विक संदर्भ में, एक obj के अंदर और दूसरा obj के अंदरूनी हिस्से के अंदर। जावास्क्रिप्ट स्थानीय गो ग्लोबल से स्कोप चेन ऊपर जाकर एक विशेष संदर्भ में पहचानकर्ताओं को हल करती है।


कुछ स्थान जहां thisविभेदित किया जा सकता है

किसी वस्तु की विधि कहलाना

var status = 1;
var helper = {
    status : 2,
    getStatus: function () {
        return this.status;
    }
};

var theStatus1 = helper.getStatus(); //line1
console.log(theStatus1); //2

var theStatus2 = helper.getStatus;
console.log(theStatus2()); //1

जब लाइन 1 को निष्पादित किया जाता है, तो जावास्क्रिप्ट फ़ंक्शन कॉल के लिए एक निष्पादन संदर्भ (ईसी) स्थापित करता है, जो कि अंतिम से पहले आए ऑब्जेक्ट द्वारा संदर्भित ऑब्जेक्ट पर सेट thisहोता है "।" । तो अंतिम पंक्ति में आप समझ सकते हैं कि a()वैश्विक संदर्भ में निष्पादित किया गया था जो कि है window

कंस्ट्रक्टर के साथ

this बनाया जा रहा वस्तु को संदर्भित करने के लिए इस्तेमाल किया जा सकता है

function Person(name){
    this.personName = name;
    this.sayHello = function(){
        return "Hello " + this.personName;
    }
}

var person1 = new Person('Scott');
console.log(person1.sayHello()); //Hello Scott

var person2 = new Person('Hugh');
var sayHelloP2 = person2.sayHello;
console.log(sayHelloP2()); //Hello undefined

जब नया Person()निष्पादित किया जाता है, तो एक पूरी तरह से नई वस्तु बनाई जाती है। Personकहा जाता है और यह thisउस नई वस्तु को संदर्भित करने के लिए सेट है।

फंक्शन कॉल

function testFunc() {
    this.name = "Name";
    this.myCustomAttribute = "Custom Attribute";
    return this;
}

var whatIsThis = testFunc();
console.log(whatIsThis); //window

var whatIsThis2 = new testFunc();
console.log(whatIsThis2);  //testFunc() / object

console.log(window.myCustomAttribute); //Custom Attribute 

यदि हम newकीवर्ड को याद करते हैं , whatIsThisतो सबसे अधिक वैश्विक संदर्भ को संदर्भित करता है जो इसे पा सकता है ( window)

घटना संचालकों के साथ

यदि ईवेंट हैंडलर इनलाइन है, तो thisवैश्विक ऑब्जेक्ट को संदर्भित करता है

<script type="application/javascript">
    function click_handler() {
        alert(this); // alerts the window object
    }
</script>

<button id='thebutton' onclick='click_handler()'>Click me!</button>

जावास्क्रिप्ट के माध्यम से ईवेंट हैंडलर को जोड़ने पर, thisडोम तत्व को संदर्भित करता है जिसने ईवेंट उत्पन्न किया।



5

"यह" का मान "संदर्भ" पर निर्भर करता है जिसमें फ़ंक्शन निष्पादित होता है। संदर्भ कोई भी वस्तु या वैश्विक वस्तु हो सकती है, अर्थात, विंडो।

तो "यह" का शब्दार्थ पारंपरिक ओओपी भाषाओं से अलग है। और यह समस्याओं का कारण बनता है: 1. जब एक फ़ंक्शन दूसरे चर (सबसे अधिक संभावना है, एक कॉलबैक) को पारित किया जाता है; और 2. जब किसी वर्ग के सदस्य विधि से एक आह्वान किया जाता है।

दोनों ही मामलों में, यह विंडो पर सेट है।


3

whould यह मदद? (जावास्क्रिप्ट में 'इस' का अधिकांश भ्रम इस तथ्य से आ रहा है कि यह आम तौर पर आपकी वस्तु से जुड़ा नहीं है, लेकिन वर्तमान निष्पादन की गुंजाइश के लिए - यह ठीक नहीं है कि यह कैसे काम करता है, लेकिन हमेशा मुझे ऐसा लगता है - पूर्ण विवरण के लिए लेख देखें)


1
यह कहना बेहतर होगा कि यह " वर्तमान निष्पादन संदर्भ से जुड़ा हुआ है "। ईएस 6 को छोड़कर (ड्राफ्ट) तीर कार्यों के साथ बदलता है, जहां यह बाहरी निष्पादन संदर्भ पर हल किया जाता है।
RobG

3

इस बारे में थोड़ी जानकारी कीवर्ड के

आइए thisकिसी भी अधिक कोड के बिना वैश्विक दायरे में कंसोल पर लॉग इन करें लेकिन

console.log(this)

में क्लाइंट / ब्राउज़र this कीवर्ड एक वैश्विक वस्तु है जो हैwindow

console.log(this === window) // true

तथा

में सर्वर / नोड / जावास्क्रिप्ट क्रम this कीवर्ड भी एक वैश्विक वस्तु है जो हैmodule.exports

console.log(this === module.exports) // true
console.log(this === exports) // true

ध्यान रखें कि exportsयह केवल एक संदर्भ हैmodule.exports


1

इस तरह से स्कोप के लिए इस का उपयोग करें

  <script type="text/javascript" language="javascript">
$('#tbleName tbody tr').each(function{
var txt='';
txt += $(this).find("td").eq(0).text();
\\same as above but synatx different
var txt1='';
 txt1+=$('#tbleName tbody tr').eq(0).text();
alert(txt1)
});
</script>

txt1 और txt का मूल्य उपरोक्त उदाहरण $ (यह) = $ ('# tbleName tbody tr') में समान है। समान है


1

मेरा एक अलग रूप है this उन अन्य उत्तरों से है जो मुझे आशा है कि सहायक हैं।

जावास्क्रिप्ट को देखने का एक तरीका यह देखना है कि फ़ंक्शन 1 को कॉल करने का केवल 1 तरीका है । यह है

functionObject.call(objectForThis, arg0, arg1, arg2, ...);

हमेशा कुछ मूल्य दिया जाता है objectForThis

बाकी सब कुछ के लिए सिंथेटिक चीनी है functionObject.call

इसलिए, बाकी सभी चीजों का वर्णन किया जा सकता है कि यह किस प्रकार अनुवाद करता है functionObject.call

यदि आप किसी फ़ंक्शन को कॉल करते हैं तो this"ग्लोबल ऑब्जेक्ट" है जो ब्राउज़र में विंडो है

function foo() {
  console.log(this);
}

foo();  // this is the window object

दूसरे शब्दों में,

foo();

प्रभावी ढंग से अनुवाद किया गया था

foo.call(window);

ध्यान दें कि यदि आप सख्त मोड का उपयोग करते हैं तो thisहोगाundefined

'use strict';

function foo() {
  console.log(this);
}

foo();  // this is the window object

जिसका मतलब है

दूसरे शब्दों में,

foo();

प्रभावी ढंग से अनुवाद किया गया था

foo.call(undefined);

जावास्क्रिप्ट में तरह ऑपरेटरों देखते हैं +और -और *। डॉट ऑपरेटर भी है जो है.

.ऑपरेटर जब सही पर एक समारोह और छोड़ दिया पर एक वस्तु के साथ प्रयोग किया प्रभावी रूप से इसका मतलब है "पास वस्तु के रूप मेंthis कार्य करने के लिए।

उदाहरण

const bar = {
  name: 'bar',
  foo() { 
    console.log(this); 
  },
};

bar.foo();  // this is bar

दूसरे शब्दों में bar.foo()अनुवादconst temp = bar.foo; temp.call(bar);

ध्यान दें कि यह कोई फर्क नहीं पड़ता कि फ़ंक्शन कैसे बनाया गया था (ज्यादातर ...)। ये सभी एक ही परिणाम का उत्पादन करेंगे

const bar = {
  name: 'bar',
  fn1() { console.log(this); },
  fn2: function() { console.log(this); },
  fn3: otherFunction,
};

function otherFunction() { console.log(this) };

bar.fn1();  // this is bar
bar.fn2();  // this is bar
bar.fn3();  // this is bar

फिर से इन सभी के लिए बस वाक्य रचना चीनी हैं

{ const temp = bar.fn1; temp.call(bar); }
{ const temp = bar.fn2; temp.call(bar); }
{ const temp = bar.fn3; temp.call(bar); }

एक अन्य शिकन प्रोटोटाइप श्रृंखला है। जब आप a.bजावास्क्रिप्ट का उपयोग करते हैं, तो पहले aसंपत्ति के लिए सीधे संदर्भित ऑब्जेक्ट पर दिखता है b। यदि bऑब्जेक्ट पर नहीं पाया जाता है, तो जावास्क्रिप्ट ऑब्जेक्ट के प्रोटोटाइप को खोजने के लिए दिखेगा b

किसी ऑब्जेक्ट के प्रोटोटाइप को परिभाषित करने के विभिन्न तरीके हैं, 2019 में सबसे आम है classकीवर्ड। के प्रयोजनों के लिए thisहालांकि यह कोई फर्क नहीं पड़ता। क्या मायने रखता है कि जैसा कि यह aसंपत्ति के लिए वस्तु में दिखता है bअगर यह bवस्तु पर संपत्ति पाता है या यह प्रोटोटाइप श्रृंखला में है यदि bएक फ़ंक्शन होने के बाद समाप्त होता है तो ऊपर दिए गए समान नियम। फ़ंक्शन bसंदर्भों को callविधि और पासिंग का उपयोग करके बुलाया जाएगाa ऑब्जेक्टफॉर के रूप में किया जाएगा जैसा कि इस उत्तर के शीर्ष पर दिखाया गया है।

अभी। आइए कल्पना करें कि हम एक फ़ंक्शन बनाते हैं जो स्पष्ट रूप thisसे दूसरे फ़ंक्शन को कॉल करने से पहले सेट करता है और फिर इसे .(डॉट) ऑपरेटर के साथ कॉल करता है

function foo() {
  console.log(this);
}

function bar() {
  const objectForThis = {name: 'moo'}
  foo.call(objectForThis);  // explicitly passing objectForThis
}

const obj = {
  bar,
};

obj.bar();  

उपयोग करने के लिए अनुवाद के बाद call, obj.bar()बन जाता है const temp = obj.bar; temp.call(obj);। जब हम barफ़ंक्शन में प्रवेश करते हैं तो हम कॉल करते हैं, fooलेकिन हम स्पष्ट रूप से ऑब्जेक्टफॉर के लिए किसी अन्य ऑब्जेक्ट में पास हो जाते हैं, इसलिए जब हम फू पर पहुंचते हैंthis वह आंतरिक ऑब्जेक्ट होता है।

यह वही है जो दोनों कार्य करता है bindऔर =>प्रभावी ढंग से करता है। वे अधिक संश्लिष्ट चीनी हैं। वे प्रभावी रूप से एक नए अदृश्य फ़ंक्शन का निर्माण ठीक उसी तरह से barऊपर करते हैं, जो स्पष्ट रूप से सेट करता है thisकि जो भी फ़ंक्शन निर्दिष्ट है। बाँध के मामले में thisआप जो भी पास करते हैं, उसके लिए निर्धारित है bind

function foo() {
  console.log(this);
}

const bar = foo.bind({name: 'moo'});

// bind created a new invisible function that calls foo with the bound object.

bar();  

// the objectForThis we are passing to bar here is ignored because
// the invisible function that bind created will call foo with with
// the object we bound above

bar.call({name: 'other'});

ध्यान दें कि यदि functionObject.bindमौजूद नहीं था तो हम इस तरह से अपना खुद का बना सकते हैं

function bind(fn, objectForThis) {
  return function(...args) {
    return fn.call(objectForthis, ...args);
  };
}

और फिर हम इसे इस तरह कह सकते हैं

function foo() {
  console.log(this);
}

const bar = bind(foo, {name:'abc'});

एरो फ़ंक्शंस, =>ऑपरेटर बाइंड के लिए सिंटैक्टिक शुगर है

const a = () => {console.log(this)};

के समान है

const tempFn = function() {console.log(this)}; 
const a = tempFn.bind(this);

ठीक उसी तरह bind, एक नया अदृश्य फ़ंक्शन बनाया जाता है जो दिए गए फ़ंक्शन को एक बाध्य मान के साथ कॉल करता है, objectForThisलेकिन bindबाध्य होने वाली वस्तु के विपरीत है। यह जो कुछ भी thisहोता है जब होता है=> ऑपरेटर का उपयोग किया जाता है।

तो, ऊपर दिए गए नियमों की तरह

const a = () => { console.log(this); }  // this is the global object
'use strict';
const a = () => { console.log(this); }  // this is undefined
function foo() {
  return () => { console.log(this); }
}

const obj = {
  foo,
};
const b = obj.foo();
b();

obj.foo()करने के लिए अनुवाद const temp = obj.foo; temp.call(obj);है जिसका अर्थ है तीर ऑपरेटर अंदर fooबाध्य होगा objएक नई अदृश्य कार्य करने के लिए और है कि नए अदृश्य समारोह जो करने के लिए असाइन किया गया है लौटने bb()हमेशा की तरह काम करेगा b.call(window)या बनाए b.call(undefined)गए नए अदृश्य फ़ंक्शन को कॉल करेगा foo। वह अदृश्य फ़ंक्शन इसमें thisपारित किए गए को अनदेखा करता है और objऑब्जेक्ट फ़ंक्शन के रूप में गुजरता है ।

ऊपर दिया गया कोड अनुवाद करता है

function foo() {
  function tempFn() {
    console.log(this);
  }
  return tempFn.bind(this);
}

const obj = {
  foo,
};
const b = obj.foo();
b.call(window or undefined if strict mode);

1 केapply समान एक और फ़ंक्शन हैcall

functionName.apply(objectForThis, arrayOfArgs);

लेकिन ईएस 6 के रूप में वैचारिक रूप से आप इसका अनुवाद भी कर सकते हैं

functionName.call(objectForThis, ...arrayOfArgs);

0

सारांश thisजावास्क्रिप्ट:

  • के मान से thisनिर्धारित किया जाता है कि फ़ंक्शन को कैसे नहीं लगाया जाता है, जहां इसे बनाया गया था!
  • आमतौर पर मूल्य thisउस वस्तु द्वारा निर्धारित किया जाता है जो डॉट से बचा हुआ है। ( windowवैश्विक अंतरिक्ष में)
  • ईवेंट श्रोताओं में this DOM तत्व को संदर्भित करने का मान है, जिस पर ईवेंट को बुलाया गया था।
  • जब फ़ंक्शन को newकीवर्ड के साथ thisनव निर्मित ऑब्जेक्ट को संदर्भित करता है का मान कहा जाता है
  • आप का मूल्य में हेरफेर कर सकते हैं thisकार्यों के साथ: call, apply,bind

उदाहरण:

let object = {
  prop1: function () {console.log(this);}
}

object.prop1();   // object is left of the dot, thus this is object

const myFunction = object.prop1 // We store the function in the variable myFunction

myFunction(); // Here we are in the global space
              // myFunction is a property on the global object
              // Therefore it logs the window object
              
             

उदाहरण घटना श्रोता:

document.querySelector('.foo').addEventListener('click', function () {
  console.log(this);   // This refers to the DOM element the eventListener was invoked from
})


document.querySelector('.foo').addEventListener('click', () => {
  console.log(this);  // Tip, es6 arrow function don't have their own binding to the this v
})                    // Therefore this will log the global object
.foo:hover {
  color: red;
  cursor: pointer;
}
<div class="foo">click me</div>

उदाहरण निर्माता:

function Person (name) {
  this.name = name;
}

const me = new Person('Willem');
// When using the new keyword the this in the constructor function will refer to the newly created object

console.log(me.name); 
// Therefore, the name property was placed on the object created with new keyword.


0

"यह" ठीक से समझने के लिए किसी को उनके बीच के संदर्भ और दायरे और अंतर को समझना चाहिए।

स्कोप : जावास्क्रिप्ट दायरे में चर की दृश्यता से संबंधित है, फ़ंक्शन के उपयोग के माध्यम से गुंजाइश प्राप्त होती है। (दायरे के बारे में और पढ़ें)

संदर्भ : संदर्भ वस्तुओं से संबंधित है। यह उस वस्तु को संदर्भित करता है जिससे कोई फ़ंक्शन संबंधित है। जब आप जावास्क्रिप्ट "इस" कीवर्ड का उपयोग करते हैं, तो यह उस ऑब्जेक्ट को संदर्भित करता है जो फ़ंक्शन के अंतर्गत आता है। उदाहरण के लिए, किसी फ़ंक्शन के अंदर, जब आप कहते हैं: "this.accoutNumber", आप संपत्ति "accoutNumber" का उल्लेख कर रहे हैं, जो उस फ़ंक्शन से संबंधित है जो उस फ़ंक्शन से संबंधित है।

यदि ऑब्जेक्ट "myObj" में "getMyName" नामक एक विधि है, जब जावास्क्रिप्ट कीवर्ड "this" का उपयोग "getMyName" के अंदर किया जाता है, तो यह "myObj" को संदर्भित करता है। यदि फ़ंक्शन "getMyName" को वैश्विक दायरे में निष्पादित किया गया था, तो "यह" विंडो ऑब्जेक्ट (सख्त मोड को छोड़कर) को संदर्भित करता है।

अब कुछ उदाहरण देखते हैं:

    <script>
        console.log('What is this: '+this);
        console.log(this);
    </script>

ब्राउज़र आउटपुट में रननिग एबोव कोड होगा: यहां छवि विवरण दर्ज करें

आउटपुट के अनुसार आप विंडो ऑब्जेक्ट के संदर्भ में हैं, यह भी दिखाई देता है कि विंडो प्रोटोटाइप ऑब्जेक्ट को संदर्भित करता है।

अब चलो एक फंक्शन के अंदर कोशिश करते हैं:

    <script>
        function myFunc(){
            console.log('What is this: '+this);
            console.log(this);
        }
        myFunc();
    </script>

आउटपुट:

यहां छवि विवरण दर्ज करें आउटपुट वैसा ही है क्योंकि हमने वैश्विक दायरे में 'इस' वैरिएबल को लॉग किया और हमने इसे फंक्शनल स्कोप में लॉग इन किया, हमने संदर्भ नहीं बदला। दोनों ही मामलों में संदर्भ समान था, विधवा वस्तु से संबंधित ।

अब हम अपनी वस्तु बनाते हैं। जावास्क्रिप्ट में, आप कई तरीकों से एक ऑब्जेक्ट बना सकते हैं।

 <script>
        var firstName = "Nora";
        var lastName = "Zaman";
        var myObj = {
            firstName:"Lord",
            lastName:'Baron',
            printNameGetContext:function(){
                console.log(firstName + " "+lastName);
                console.log(this.firstName +" "+this.lastName);
                return this;
            }
        }

      var context = myObj.printNameGetContext();
      console.log(context);
    </script>

आउटपुट: यहां छवि विवरण दर्ज करें

इसलिए उपर्युक्त उदाहरण से, हमने पाया कि 'यह' कीवर्ड एक नए संदर्भ का संदर्भ दे रहा है जो myObj से संबंधित है, और myObject में प्रोटोटाइप चेन टू ऑब्जेक्ट भी है।

चलो एक और उदाहरण फेंकते हैं:

<body>
    <button class="btn">Click Me</button>
    <script>
        function printMe(){
            //Terminal2: this function declared inside window context so this function belongs to the window object.
            console.log(this);
        }
        document.querySelector('.btn').addEventListener('click', function(){
            //Terminal1: button context, this callback function belongs to DOM element 
            console.log(this);
            printMe();
        })
    </script>
</body>

आउटपुट: सही समझ में आता है? (टिप्पणी पढ़ें) यहां छवि विवरण दर्ज करें

यदि आपको ऊपर दिए गए उदाहरण को समझने में परेशानी हो रही है तो आइए अपने स्वयं के कॉलबैक के साथ प्रयास करें;

<script>
        var myObj = {
            firstName:"Lord",
            lastName:'Baron',
            printName:function(callback1, callback2){
                //Attaching callback1 with this myObj context
                this.callback1 = callback1;
                this.callback1(this.firstName +" "+this.lastName)
                //We did not attached callback2 with myObj so, it's reamin with window context by default
                callback2();
                /*
                 //test bellow codes
                 this.callback2 = callback2;
                 this.callback2();
                */
            }
        }
        var callback2 = function (){
            console.log(this);
        }
        myObj.printName(function(data){
            console.log(data);
            console.log(this);
        }, callback2);
    </script>

उत्पादन: यहां छवि विवरण दर्ज करें

अब आइए समझें स्कोप, स्व, आईआईएफई और यह कैसे व्यवहार करता है

       var color = 'red'; // property of window
       var obj = {
           color:'blue', // property of window
           printColor: function(){ // property of obj, attached with obj
               var self = this;
               console.log('In printColor -- this.color: '+this.color);
               console.log('In printColor -- self.color: '+self.color);
               (function(){ // decleard inside of printColor but not property of object, it will executed on window context.
                    console.log(this)
                    console.log('In IIFE -- this.color: '+this.color);
                    console.log('In IIFE -- self.color: '+self.color); 
               })();

               function nestedFunc(){// decleard inside of printColor but not property of object, it will executed on window context.
                    console.log('nested fun -- this.color: '+this.color);
                    console.log('nested fun -- self.color: '+self.color);
               }

               nestedFunc(); // executed on window context
               return nestedFunc;
           }
       };

       obj.printColor()(); // returned function executed on window context
   </script> 

आउटपुट बहुत बढ़िया सही है? यहां छवि विवरण दर्ज करें


-1

सरल उत्तर:

"यह" कीवर्ड हमेशा मंगलाचरण के संदर्भ पर निर्भर है। उनका उल्लेख नीचे किया गया है।

  1. समारोह नए कुंजी के साथ कहा जाता है

    यदि फ़ंक्शन को नए कीवर्ड के साथ बुलाया जाता है, तो THIS नए बनाए गए ऑब्जेक्ट के लिए बाध्य होगा।

    function Car(){
      this.name="BMW";
    }
    const myCar=new Car();
    myCar.name; // output "BMW"

    ऊपर में यह 'myCar' ऑब्जेक्ट के लिए बाध्य होगा

  2. समारोह का विस्तार से कॉल और आवेदन विधि का उपयोग किया जाता है।

    इस मामले में, यह उस वस्तु के लिए बाध्य होगा जो स्पष्ट रूप से फ़ंक्शन में पारित हो जाती है।

    var obj1={"name":"bond"};
    function printMessage(msg){
        return msg+" "+this.name;
    }
    const message=printMessage.call(obj1,"my name is ");
    console.log(message); //HERE THIS WILL BE BOUND TO obj1 WHICH WE PASSED EXPLICITLY. SAME FOR APPLY METHOD ALSO.
  3. अगर फंक्शन का सही तरीके से पालन किया जाता है, तो यह जरूरी है कि आप इस जॉब से पहले मिल जाएं

    var obj1={
       "name":"bond",
        getName: function () {
                    return this.name;
                 }
    };
    const newname=obj1.getName();
    console.log(newname); //HERE THIS WILL BE BOUND TO obj1(WHITCHEVER OBJECT IS MENTIONED BEFORE THE DOT THIS WILL BE BOUND TO THAT)
  4. जब भी कोई मौका मिलता है, तब तक वह किसी भी तरह से किया जा सकता है, जो अंतर्राष्ट्रीय स्तर पर किया जाएगा।

    const util = {
       name: 'Utility',
       getName: function () {
                    return this.name;
    };
    
    const getName=util.getName;
    const newName=getName();
    console.log(newName); // IF THIS EXECUTED IN BROWSER THIS WILL BE  BOUND TO WINDOW OBJECT. IF THIS EXECUTED IN SERVER THIS WILL BE BOUND TO GLOBAL OBJECT
  5. इस मोड में यह प्रमाणित नहीं किया जाएगा

    function setName(name){
        "use strict"
        return this.name;
    }
    setName(); //WILL BE ERROR SAYING name IS UNDEFINED. 
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.