कड़ाई से उपयोग करने पर एक अनाम फ़ंक्शन में "यह" अपरिभाषित क्यों है?


85

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

उदाहरण:

(function () {
    "use strict";

    this.foo = "bar"; // *this* is undefined, why?
}());

एक पहेली में परीक्षण करें : http://jsfiddle.net/Pyr5g/1/ लकड़हारा (फायरबग) देखें।


4
ध्यान दें कि इसका अनाम कार्यों से कोई लेना-देना नहीं है, लेकिन आह्वान विधि। इस संशोधित फ़िडल को देखें (कंसोल लॉग में देखें)।
फ्रॉग्ज

@Phrogz: यह वह जगह हो सकती है जहां से कुछ भ्रम उत्पन्न हुआ। यह बात बताने के लिए धन्यवाद।
टी। जंगहंस

जवाबों:


101

ऐसा इसलिए है, क्योंकि ECMAscript 262 संस्करण 5 तक, अगर लोग जहां का उपयोग कर रहे हैं constructor pattern, तो एक बड़ा भ्रम था कि newकीवर्ड का उपयोग करना भूल गए । यदि आप newES3 में एक कंस्ट्रक्टर फ़ंक्शन को कॉल करते समय उपयोग करना भूल गए , thisतो वैश्विक ऑब्जेक्ट ( windowएक ब्राउज़र में) को संदर्भित किया और आप वैरिएबल के साथ वैश्विक ऑब्जेक्ट को क्लॉबर करेंगे।

यह भयानक व्यवहार था और इसलिए ECMA में लोगों ने निर्णय लिया, बस करने के thisलिए undefined

उदाहरण:

function myConstructor() {
    this.a = 'foo';
    this.b = 'bar';
}

myInstance     = new myConstructor(); // all cool, all fine. a and b were created in a new local object
myBadInstance  = myConstructor(); // oh my gosh, we just created a, and b on the window object

अंतिम पंक्ति ES5 सख्त में एक त्रुटि फेंक देगी

"TypeError: this is undefined"

(जो बेहतर व्यवहार है)


4
यह समझ में आता है। क्या आपके पास कथन का बैक अप लेने का संदर्भ है?
रोब डब्ल्यू

1
@ रॉब: मुझे खुद को खोजना होगा, लेकिन मैंने डगलस क्रॉकफोर्ड को कई बार सुना, जहां उन्होंने कहा, यह उस फैसले का कारण था।
jAndy

1
इसका उल्लेख जावास्क्रिप्ट में है: द गुड पार्ट्स फ्रॉम क्रॉकफ़ोर्ड। इसका विस्तार से वर्णन किया गया है। हालांकि ECMAs के फैसले के बारे में नहीं।
मद्र

1
यह तार्किक कारण है कि सख्त मोड इसे अपरिभाषित करता है। अन्य तार्किक कारण दक्षता है, अन्य तार्किक कारण यह है कि this === windowभ्रामक है और कार्यों में टोकन के रूप में वैश्विक गुंजाइश को लीक करता है
रेयनोस

2
@jAndy: उत्तर के लिए धन्यवाद। यह समझ में आता है। मैं भी करने के लिए परिवर्तन की एक कॉम्पैक्ट स्पष्टीकरण पाया इस पर javascriptweblog.wordpress.com/2011/05/03/... : "सबसे विशेष रूप से, अगर पहला तर्क पर कॉल करें या लागू करने के लिए अशक्त या अपरिभाषित, इस लागू फंक्शन का मान है वैश्विक वस्तु में परिवर्तित नहीं किया जाएगा। ”
टी। जंगहंस

15

एक तंत्र है जिसे "बॉक्सिंग" thisकहा जाता है, जो कॉल किए गए फ़ंक्शन के संदर्भ में प्रवेश करने से पहले ऑब्जेक्ट को लपेटता है या बदल देता है । आपके मामले में, का मान thisहोना चाहिए undefinedक्योंकि आप फ़ंक्शन को ऑब्जेक्ट की विधि के रूप में नहीं बुला रहे हैं। यदि गैर सख्त मोड, इस मामले में, यह windowऑब्जेक्ट द्वारा प्रतिस्थापित किया जाता है। में strictमोड यह हमेशा अपरिवर्तित है, कारण है कि यह है कि undefinedयहाँ।

आप https://developer.mozilla.org/en/JavaScript/Strict_mode पर अधिक जानकारी प्राप्त कर सकते हैं


@samuel तो हम सख्त मोड में विंडो ऑब्जेक्ट के लिए एक चर कैसे असाइन कर सकते हैं ??
नल पॉइंटर

8

इस स्टैक ओवरफ्लो जवाब के अनुसार , आप thisगुमनाम कार्यों के अंदर उपयोग कर सकते हैं , बस .call(this)इसके अंत में कॉल करके ।

(function () {
    "use strict";

    this.foo = "bar";
}).call(this);

4
ध्यान दें कि इस मामले में वस्तु thisहोगी Window, जो वांछित नहीं हो सकती है
निन्जाकन्नन

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