जावास्क्रिप्ट में इस और स्व के बीच अंतर


118

सभी को thisजावास्क्रिप्ट के बारे में पता है , लेकिन selfजंगली में भी सामना करने के उदाहरण हैं, जैसे कि यहां

तो, thisऔर selfजावास्क्रिप्ट में क्या अंतर है ?



8
@ डायस्ट्रो: एक है: window.self( === window)। हालांकि ओपी का शायद एक तुच्छ चर नाम है ...
बर्गी

2
@ डिस्ट्रॉय: वास्तव में मुझे नहीं लगा कि वह वास्तव में इसका मतलब निकाल सकता है, लेकिन वास्तव में वैश्विक दायरे में (और एक ब्राउज़र वातावरण) this === selfसच है :-)
बर्गी

2
अलग-अलग विषय: अतुल्यकालिक प्रोग्रामिंग के परिणामस्वरूप, कॉलबैक नेस्टिंग के कई (अच्छी तरह से, एक से अधिक खराब है) स्तरों के साथ कोड होना आम है, आजकल इसके thisलिए अलियासिंग करना selfएक महान अभ्यास नहीं है। इसके बजाय अधिक वर्णनात्मक नाम का उपयोग करें। thisवस्तुतः नाम बोलना ही कोई जानकारी नहीं है और यह केवल नाम का एक गैर-पसंद विकल्प है क्योंकि वर्ग परिभाषा का शाब्दिक संदर्भ इसे योग्य बनाता है।
मिलीमोउ

2
यह एक वैध और उपयोगी प्रश्न है, इसे फिर से खोल दिया जाना चाहिए
danza

जवाबों:


127

जब तक कहीं और निर्धारित करते हैं, का मान selfहै windowक्योंकि जावास्क्रिप्ट आप किसी भी संपत्ति तक पहुंचने देता है xकी windowबस के रूप में x, के बजाय window.x। इसलिए, selfवास्तव में है window.self, जो अलग है this

window.self === window; // true

यदि आप एक ऐसे कार्य का उपयोग कर रहे हैं जिसे वैश्विक दायरे में निष्पादित किया गया है और यह सख्त मोड में नहीं है, तो यह thisचूक है window, और इसलिए

function foo() {
    console.log(
        window.self === window, // is self window?
        window.self === this,   // is self this?
        this === window         // is this window?
    );
}
foo(); // true true true

यदि आप किसी अन्य संदर्भ में फ़ंक्शन का उपयोग कर रहे हैं, thisतो उस संदर्भ को संदर्भित करेगा, लेकिन selfफिर भी रहेगा window

// invoke foo with context {}
foo.call({}); // true false false

आप यहाँ विंडो ऑब्जेक्ट के लिए W3C 2006 वर्किंग ड्राफ्टwindow.self में परिभाषित पा सकते हैं ।


34
पूर्णता के लिए, selfवेबवर्कर के संदर्भ में उपयोगी होता है जब विंडो सुलभ नहीं होती है ( developer.mozilla.org/en-US/docs/Web/Guide/Performance/… )। का उपयोग selfकरने के बजाय windowआप एक पोर्टेबल तरह से वैश्विक वस्तु पहुंचने देता है।
19

24

इसका एक मामूली जोड़ यह है कि लोग सेवा कर्मियों के संदर्भ में इसका सामना कर सकते हैं, इस मामले में इसका मतलब कुछ अलग है।

आप इसे सेवा कार्यकर्ता मॉड्यूल में देख सकते हैं:

self.addEventListener('install', function(e) {
  console.log('[ServiceWorker] Install');
});

यहाँ स्वयं वर्करग्लोस्कोप को संदर्भित करता है, और यह ईवेंट श्रोताओं को स्थापित करने के लिए मानक विधि है।

से मोज़िला डॉक्स :

स्वयं का उपयोग करके, आप वैश्विक स्कोप को इस तरह से संदर्भित कर सकते हैं जो न केवल एक खिड़की के संदर्भ में काम करेगा (स्वयं विंडो के लिए हल होगा)


धन्यवाद ! मैं इस उत्तर के लिए :) देख रहा था
agpt

23

हालाँकि मुझे यहाँ देर हो रही है लेकिन मैं एक उदाहरण भर में आया हूँ जो thisआगे समझने में मददगार हो सकता है:

var myObject = {
 foo: "bar",
 func: function() {
    var self = this;
    console.log("outer func:  this.foo = " + this.foo);
    console.log("outer func:  self.foo = " + self.foo);
    (function() {
        console.log("inner func:  this.foo = " + this.foo);
        console.log("inner func:  self.foo = " + self.foo);
    }());
  }
};
myObject.func();

ओ / पी

outer func:  this.foo = bar
outer func:  self.foo = bar
inner func:  this.foo = undefined
inner func:  self.foo = bar

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


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

2

ECMA 5 के संदर्भ को स्पष्ट करने की आवश्यकता है।

मेरा मानना ​​है कि इसका अर्थ है ECMA-262 संस्करण 5. यह ध्यान दिया जाना चाहिए कि ECMA-262 (उर्फ ECMAScript या, कम सटीक, जावास्क्रिप्ट) एक सामान्य स्क्रिप्टिंग भाषा है जिसे इंटरनेट ब्राउज़रों में लागू किया गया है । संस्करण 5.1 मानक से:

फ़ंक्शन ऑब्जेक्ट F में समाहित फ़ंक्शन कोड के लिए नियंत्रण के संदर्भ में निष्पादन के चरण में प्रवेश करते समय निम्न चरणों का पालन किया जाता है, एक कॉलर ने यह प्रदान किया है, और एक कॉल करने वाले ने तर्क दिया:

  1. यदि फ़ंक्शन कोड सख्त कोड है, तो ThisBinding को thisArg पर सेट करें।
  2. यदि यह आधार शून्य या अपरिभाषित है, तो इस ऑब्जेक्ट को वैश्विक ऑब्जेक्ट पर सेट करें।
  3. यदि टाइप (thisArg) ऑब्जेक्ट नहीं है, तो इसे ToBbject (ThisArg) पर सेट करें।
  4. Els ने TheBinding को thisArg पर सेट किया
  5. ... ("इस" के बारे में नहीं)

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

तो सवाल का जवाब है:

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

"स्व" का कोई विशेष वाक्यगत अर्थ नहीं है, यह सिर्फ एक पहचानकर्ता है। ब्राउज़र्स विंडो को परिभाषित करते हैं। स्वयं (वैश्विक विंडो ऑब्जेक्ट की एक संपत्ति) = विंडो। यह "स्व" के अयोग्य सन्दर्भों के परिणामस्वरूप "विंडो" के समान होता है "स्वयं" को "एनक्लोजिंग स्कोप" के रूप में फिर से परिभाषित किया गया है (जैसे कि "var self = this?" ऊपर "। सौभाग्य" "इसे" पुन: परिभाषित करना)।

तो ऊपर दिए गए उदाहरण का पूरा विवरण है:

outer func:  this.foo = bar
// "this" refers to the invoking object "myObject"
outer func:  self.foo = bar
// "self" resolves to the variable in the local scope which has been set to "this" so it is also "myObject"
inner func:  this.foo = undefined
// "this" refers to the invoking object (none) and so is replaced by the global object (strict mode must be off). "window" has no foo property so its "value" is undefined.
inner func:  self.foo = bar
// self resolves to the variable in the enclosing scope which is still "myObject"

उदाहरण की एक दिलचस्प भिन्नता आंतरिक फ़ंक्शन के संदर्भ को वापस करके एक बंद बनाता है।

var myObject = {
 foo: "bar",
 func: function() {
    var self = this;
    console.log("outer func:  this.foo = " + this.foo);
    console.log("outer func:  self.foo = " + self.foo);
    return function() {
        console.log("inner func:  this.foo = " + this.foo);
        console.log("inner func:  self.foo = " + self.foo);
    };
  }
};
var yourObject = {
 foo: "blat",
 func: myObject.func() // function call not function object
};
console.log("----");
yourObject.func();

उत्पादन

outer func:  this.foo = bar
outer func:  self.foo = bar
----
inner func:  this.foo = blat
inner func:  self.foo = bar

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

सारांश के सारांश को सारांशित करने के लिए, "यह" भाषा मानक द्वारा परिभाषित किया गया है, "स्व" को परिभाषित किया गया है जो कोई भी इसे परिभाषित करता है (रनटाइम कार्यान्वयनकर्ता या अंत प्रोग्रामर)।


0

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

console.log( window ); // Window {…}
console.log( self );   // Window {…}
console.log( this );   // Window {…}

console.log( window.window ); // Window {…}
console.log( window.self );   // Window {…}
console.log( window.this );   // undefined  

console.log( self.self );     // Window {…}
console.log( self.window );   // Window {…}
console.log( self.this );     // undefined

console.log( this.this );     // undefined
console.log( this.window );   // Window {…}
console.log( this.self );     // Window {…}

console.log( window.window.window );    // Window {…}
console.log( self.self.self );          // Window {…}
console.log( window.self.window.self ); // Window {…}
console.log( self.window.self.window ); // Window {…}
console.log( this.this );               // undefined
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.