क्या करता है 'var = यह?' जावास्क्रिप्ट में मतलब है?


351

एक जावास्क्रिप्ट फ़ाइल में मैंने देखा:

function Somefunction(){
   var that = this; 
   ... 
}

इसे घोषित करने thatऔर नियत करने का उद्देश्य क्या है this?



6
तीर कार्यों के लिए "यह" और "उस" हैक की आवश्यकता नहीं है। तीर फ़ंक्शन के साथ "यह" अपेक्षा के अनुरूप काम करता है। अधिक जानकारी के लिए यहाँ देखें ES6 इन डेप्थ: एरो फ़ंक्शंस
सतगुरु श्रीवास्तव

1
यहाँ इस अवधारणा को समझाया गया है scotch.io/@alZami/understanding-this-in-javascript
AL-zami

रहस्यमय संदर्भ पर एक महान विवरण यहाँ
RBT

नवीनतम और अद्यतन स्पष्टीकरण यहां
सुकृत गुप्ता

जवाबों:


485

मैं इस उत्तर को दृष्टांत के साथ शुरू करने जा रहा हूं:

var colours = ['red', 'green', 'blue'];
document.getElementById('element').addEventListener('click', function() {
    // this is a reference to the element clicked on

    var that = this;

    colours.forEach(function() {
        // this is undefined
        // that is a reference to the element clicked on
    });
});

मेरे उत्तर ने मूल रूप से jQuery के साथ इसका प्रदर्शन किया, जो केवल थोड़ा अलग है:

$('#element').click(function(){
    // this is a reference to the element clicked on

    var that = this;

    $('.elements').each(function(){
        // this is a reference to the current element in the loop
        // that is still a reference to the element clicked on
    });
});

क्योंकि thisअक्सर जब आप किसी नए फ़ंक्शन को कॉल करके गुंजाइश बदलते हैं, तो आप इसका उपयोग करके मूल मूल्य तक नहीं पहुंच सकते। इसे एलियास करने से thatआप मूल मूल्य तक पहुँच सकते हैं this

व्यक्तिगत रूप से, मैं thatउर्फ के रूप में उपयोग को नापसंद करता हूं । यह शायद ही कभी स्पष्ट है कि यह किसका उल्लेख कर रहा है, खासकर यदि फ़ंक्शन कुछ पंक्तियों से अधिक लंबा हो। मैं हमेशा अधिक वर्णनात्मक उपनाम का उपयोग करता हूं । उपरोक्त मेरे उदाहरणों में, मैं शायद उपयोग करूँगा clickedEl


149
मैं आमतौर पर साथ जाता हूं var self = this;। शब्द thatका अर्थ लगता है कि परिवर्तनशील कुछ भी है this
डेविड मर्डोक

13
@ डेविड मैंने सोचा है कि कुछ भ्रामक है। लेकिन अगर, जैसा कि क्रॉकफोर्ड कहते हैं, यह एक सम्मेलन है, क्या उस मार्ग से नीचे जाना बुद्धिमानी है। मैं आपके साथ पूरी तरह से सहमत हूँ, हालांकि, बहुत अधिक समझ में आता है।
एल रोनोको

4
@ एल रोन्नोको, लेकिन "उसे भूरे बाल और एक दमदार दाढ़ी मिली है और उसका तरीका एक बूढ़े व्यक्ति का ध्यान रखता है जो बच्चों को अपने लॉन से बाहर निकलने के लिए चिल्लाता है।" - blogging.compendiumblog.com/blog/software-for-humans/0/0/… ;-p
डेविड मर्डोक

7
@ElRonnoco: यह प्राधिकरण के लिए एक अपील है, हालांकि। यदि हम केवल वही करते हैं जो "प्रसिद्ध लोग" कहते हैं कि हमें करना चाहिए, तो हम आपदा के लिए नेतृत्व कर रहे हैं।
ऑर्बिट

3
forEachसमारोह में एक दूसरे वैकल्पिक तर्क है जो समारोह के बाध्यकारी है लेता है। colours.forEach(function(){/* 'this' is bound correctly --> */}, this);तो एक नोट जोड़ा जाना चाहिए जो वास्तव में आवश्यक var that = thisनहीं है । forEach
मैट क्लार्कसन

107

से Crockford

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

जेएस फिडल

function usesThis(name) {
    this.myName = name;

    function returnMe() {
        return this;        //scope is lost because of the inner function
    }

    return {
        returnMe : returnMe
    }
}

function usesThat(name) {
    var that = this;
    this.myName = name;

    function returnMe() {
        return that;            //scope is baked in with 'that' to the "class"
    }

    return {
        returnMe : returnMe
    }
}

var usesthat = new usesThat('Dave');
var usesthis = new usesThis('John');
alert("UsesThat thinks it's called " + usesthat.returnMe().myName + '\r\n' +
      "UsesThis thinks it's called " + usesthis.returnMe().myName);

यह अलर्ट ...

UseThat को लगता है कि इसे डेव कहा जाता है

उपयोग यह सोचता है कि इसे अपरिभाषित कहा जाता है


2
धन्यवाद, यह मेरे लिए काफी अच्छा है।
क्रिस

3
मैंने पढ़ा कि, समझ में नहीं आया क्योंकि इसका कोई विवरण नहीं था, Google पर खोजा, इस पृष्ठ को पाया। जहां मुझे फिर से उसी वाक्य की ओर इशारा किया गया है। इसलिए पतन।
आदित्य एमपी

3
यह एक उचित बिंदु है, मैं कहूंगा कि जावास्क्रिप्ट से अपरिचित किसी व्यक्ति को अकेले मेरे उत्तर से अवधारणा को समझने में कठिनाई होगी। मैंने बहुत संक्षेप में उत्तर दिया (और मैंने उस पृष्ठ के लिए लिंक किया जिसे आपने Googled के लिए ..) मैं कहूंगा कि lonesomeday का उत्तर सबसे स्पष्ट है, हालांकि मैंने अभी भी इसे सादे JS में पसंद किया होगा क्योंकि एक jQuery के उदाहरण के विपरीत।
एल रोन्नोको

16
मैं कोई अपराध नहीं करता। किसी ऐसे व्यक्ति को देखना अच्छा है, जो अपमानजनक टिप्पणी करता है!
एल रोन्ननो

4
क्रॉकफोर्ड के जवाब के साथ समस्या यह है कि thatचर का उपयोग उनके उदाहरण में बिल्कुल नहीं किया गया है। यह ऐसा लगता है जैसे कि बस एक चर होल्डिंग बनाना thisबाकी कोड के लिए कुछ करता है।
r3m0t

86

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

var car = {};
car.starter = {};

car.start = function(){
    var that = this;

    // you can access car.starter inside this method with 'this'
    this.starter.active = false;

    var activateStarter = function(){
        // 'this' now points to the global scope
        // 'this.starter' is undefined, so we use 'that' instead.
        that.starter.active = true;

        // you could also use car.starter, but using 'that' gives
        // us more consistency and flexibility
    };

    activateStarter();

};

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

दोनों स्कैप में कन्वेंशन द्वारा उपयोग करने के लिए एक वैरिएबल बनाना, जावास्क्रिप्ट के साथ इस सामान्य समस्या के लिए एक समाधान है (हालांकि यह jquery कार्यों में उपयोगी है, भी)। यही कारण है कि बहुत सामान्य लग नाम thatका उपयोग किया जाता है। यह भाषा में एक कमी पर काबू पाने के लिए एक आसानी से पहचाने जाने योग्य सम्मेलन है।

पर जैसा एल Ronnoco संकेत डगलस Crockford सोचता है कि यह एक अच्छा विचार है।


8
मुझे लगता है कि यह स्वीकार किए जाते हैं की तुलना में अधिक उपयोगी जवाब है। क्योंकि यह इस कारण को स्पष्ट करता है कि क्रॉकफोर्ड ने jQuery के बारे में उत्तर देते समय "कि" का आविष्कार किया है।
कॉन्सटेंटिन स्मोलैनिन

4
यह वास्तव में एक बेहतर उदाहरण है तो स्वीकृत उत्तर। यह बताता है कि यह "ईसीएमएस्क्रिप्ट भाषा विनिर्देश में एक त्रुटि के रूप में क्या है जो डगलस द्वारा कहा गया है कि यह आंतरिक कार्यों के लिए गलत तरीके से सेट किया गया है"।
काकासी जूल

1
आप इसे व्याकरण सही बनाने के लिए चाहते हो सकता है। मुझे पता है कि यह एक टाइपो की तरह अधिक है, लेकिन यह जावास्क्रिप्ट शुरुआती को भ्रमित कर सकता है क्योंकि यह प्रश्न अधिक शुरुआती जैसा है। मेरा मतलब है कि यह होना चाहिए: var कार = {}; car.starter = {}; car.start = function () {...}
kakacii

1
@kakacii धन्यवाद अब तय हो गया।
वेल्लन फ्लिन

9

के उपयोग thatवास्तव में जरूरी है अगर आप के उपयोग के साथ एक समाधान नहीं है call()या apply():

var car = {};
car.starter = {};

car.start = function(){
    this.starter.active = false;

    var activateStarter = function(){
        // 'this' now points to our main object
        this.starter.active = true;
    };

    activateStarter.apply(this);
};

3

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

एचटीएमएल

<button id="button">Alert Name</button>

जे एस

var Person = function(name) {
  this.name = name;
  var that = this;
  this.sayHi = function() {
    alert(that.name);
  };
};

var ahmad = new Person('Ahmad');
var element = document.getElementById('button');
element.addEventListener('click', ahmad.sayHi); // => Ahmad

डेमो

इच्छा से ऊपर समाधान assing thisके thatअंदर तो हम कर सकते हैं और उन तक पहुंचने नाम संपत्ति sayHiसे विधिthat , यह इतना डोम कॉल अंदर मुद्दों के बिना कहा जा सकता है।

एक अन्य उपाय यह है कि आप किसी खाली thatवस्तु को असाइन करें और उसमें गुण और विधियाँ जोड़ें और फिर उसे वापस लौटाएँ। लेकिन इस समाधान के साथ आप prototypeकंस्ट्रक्टर के खो गए।

var Person = function(name) {
  var that = {};
  that.name = name;
  that.sayHi = function() {
    alert(that.name);
  };
  return that;
};

2

यहाँ एक उदाहरण है `

$(document).ready(function() {
        var lastItem = null;
        $(".our-work-group > p > a").click(function(e) {
            e.preventDefault();

            var item = $(this).html(); //Here value of "this" is ".our-work-group > p > a"
            if (item == lastItem) {
                lastItem = null;
                $('.our-work-single-page').show();
            } else {
                lastItem = item;
                $('.our-work-single-page').each(function() {
                    var imgAlt = $(this).find('img').attr('alt'); //Here value of "this" is '.our-work-single-page'. 
                    if (imgAlt != item) {
                        $(this).hide();
                    } else {
                        $(this).show();
                    }
                });
            }

        });
    });`

तो आप देख सकते हैं कि आपके द्वारा लक्षित DOM तत्व के आधार पर इसका मूल्य दो अलग-अलग मान हैं लेकिन जब आप "उस" को ऊपर दिए गए कोड में जोड़ते हैं तो "आप" जो आप लक्ष्य कर रहे हैं उसका मान बदल जाता है।

`$(document).ready(function() {
        var lastItem = null;
        $(".our-work-group > p > a").click(function(e) {
            e.preventDefault();
            var item = $(this).html(); //Here value of "this" is ".our-work-group > p > a"
            if (item == lastItem) {
                lastItem = null;
                var that = this;
                $('.our-work-single-page').show();
            } else {
                lastItem = item;
                $('.our-work-single-page').each(function() {
                   ***$(that).css("background-color", "#ffe700");*** //Here value of "that" is ".our-work-group > p > a"....
                    var imgAlt = $(this).find('img').attr('alt'); 
                    if (imgAlt != item) {
                        $(this).hide();
                    } else {
                        $(this).show();
                    }
                });
            }

        });
    });`

..... $ (वह) .css ("पृष्ठभूमि-रंग", "# ffe700"); // यहाँ "उस" का मान है। हमारा-कार्य-समूह> p> a "क्योंकि var का मान = यह; भले ही हम "इस" = '.our-work-single-page' पर हैं, फिर भी हम पिछले DOM तत्व में हेरफेर करने के लिए "उस" का उपयोग कर सकते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.