आपको किस बारे में जानना चाहिए this
this(उर्फ "संदर्भ") प्रत्येक फ़ंक्शन के अंदर एक विशेष कीवर्ड है और इसका मान केवल इस बात पर निर्भर करता है कि फ़ंक्शन को कैसे बुलाया गया था, न कि कैसे / कब / जहां इसे परिभाषित किया गया था। यह अन्य चरों (जैसे तीर के कार्यों को छोड़कर, नीचे देखें) जैसे लेक्सिकल स्कोप से प्रभावित नहीं होता है। यहाँ कुछ उदाहरण हैं:
function foo() {
console.log(this);
}
// normal function call
foo(); // `this` will refer to `window`
// as object method
var obj = {bar: foo};
obj.bar(); // `this` will refer to `obj`
// as constructor function
new foo(); // `this` will refer to an object that inherits from `foo.prototype`
अधिक जानने के लिए this, MDN प्रलेखन पर एक नज़र डालें ।
सही का संदर्भ कैसे दें this
उपयोग न करें this
आप वास्तव thisमें विशेष रूप से उपयोग नहीं करना चाहते हैं , लेकिन यह जिस वस्तु को संदर्भित करता है । इसलिए एक आसान उपाय यह है कि बस एक नया वैरिएबल बनाया जाए जो उस ऑब्जेक्ट को भी संदर्भित करता है। चर का कोई भी नाम हो सकता है, लेकिन आम हैं selfऔर that।
function MyConstructor(data, transport) {
this.data = data;
var self = this;
transport.on('data', function() {
alert(self.data);
});
}
चूंकि selfयह एक सामान्य चर है, यह लेक्सिकल स्कोप नियमों का पालन करता है और कॉलबैक के अंदर पहुंच योग्य है। इसका यह भी फायदा है कि आप thisकॉलबैक के मूल्य तक पहुँच सकते हैं ।
स्पष्ट रूप thisसे कॉलबैक का सेट - भाग 1
ऐसा लग सकता है कि आपके मूल्य पर कोई नियंत्रण नहीं है thisक्योंकि इसका मूल्य स्वचालित रूप से सेट है, लेकिन वास्तव में ऐसा नहीं है।
प्रत्येक फ़ंक्शन में विधि .bind [डॉक्स] होती है , जो thisएक मान के साथ एक नया फ़ंक्शन लौटाती है । फ़ंक्शन का ठीक वैसा ही व्यवहार होता है जैसा कि आपने कॉल .bindकिया था, केवल वही thisआपके द्वारा सेट किया गया था। कोई फर्क नहीं पड़ता कि कैसे या जब उस फ़ंक्शन को कहा जाता है, thisहमेशा पारित मूल्य को संदर्भित करेगा।
function MyConstructor(data, transport) {
this.data = data;
var boundFunction = (function() { // parenthesis are not necessary
alert(this.data); // but might improve readability
}).bind(this); // <- here we are calling `.bind()`
transport.on('data', boundFunction);
}
इस मामले में, हम कॉलबैक के लिए बाध्यकारी हैं thisके मूल्य के MyConstructorके this।
नोट: जब jQuery के लिए बाध्यकारी संदर्भ, इसके बजाय jQuery.proxy [डॉक्स] का उपयोग करें। ऐसा करने का कारण यह है कि आपको इवेंट कॉलबैक को अनबाइंड करने पर फ़ंक्शन के संदर्भ को संग्रहीत करने की आवश्यकता नहीं है। jQuery कि आंतरिक रूप से संभालता है।
ECMAScript 6 में तीर के कार्यों का परिचय दिया गया है , जिसे लंबोदर कार्यों के रूप में माना जा सकता है। उनका अपना thisबंधन नहीं है । इसके बजाय, thisएक सामान्य चर की तरह दायरे में देखा जाता है। इसका मतलब है कि आपको कॉल नहीं करना है .bind। उनके पास केवल यही विशेष व्यवहार नहीं है, कृपया अधिक जानकारी के लिए MDN प्रलेखन देखें।
function MyConstructor(data, transport) {
this.data = data;
transport.on('data', () => alert(this.data));
}
thisकॉलबैक का सेट - भाग 2
कॉलबैक को स्वीकार करने वाले कुछ कार्य / तरीके भी एक मूल्य को स्वीकार करते हैं जिसके लिए कॉलबैक thisको संदर्भित करना चाहिए। यह मूल रूप से इसे खुद को बांधने के समान है, लेकिन फ़ंक्शन / विधि यह आपके लिए करता है। Array#map [डॉक्स] एक ऐसी विधि है। इसके हस्ताक्षर हैं:
array.map(callback[, thisArg])
पहला तर्क कॉलबैक है और दूसरा तर्क मूल्य thisको संदर्भित करना चाहिए। यहाँ एक उदाहरण दिया गया है:
var arr = [1, 2, 3];
var obj = {multiplier: 42};
var new_arr = arr.map(function(v) {
return v * this.multiplier;
}, obj); // <- here we are passing `obj` as second argument
नोट: आप thisउस फ़ंक्शन / विधि के दस्तावेज़ीकरण में आमतौर पर उल्लेखित मूल्य को पास कर सकते हैं या नहीं । उदाहरण के लिए, jQuery की $.ajaxविधि [डॉक्स] नामक एक विकल्प का वर्णन करती है context:
इस ऑब्जेक्ट को सभी अजाक्स-संबंधित कॉलबैक के संदर्भ में बनाया जाएगा।
सामान्य समस्या: कॉलबैक / ईवेंट हैंडलर के रूप में ऑब्जेक्ट विधियों का उपयोग करना
इस समस्या का एक अन्य सामान्य प्रकटीकरण तब होता है जब किसी ऑब्जेक्ट विधि का उपयोग कॉलबैक / ईवेंट हैंडलर के रूप में किया जाता है। फ़ंक्शंस जावास्क्रिप्ट में प्रथम श्रेणी के नागरिक हैं और "विधि" शब्द केवल एक फ़ंक्शन के लिए बोलचाल का शब्द है जो एक वस्तु संपत्ति का एक मूल्य है। लेकिन उस फ़ंक्शन का उसके "ऑब्जेक्ट" से कोई विशिष्ट लिंक नहीं है।
निम्नलिखित उदाहरण पर विचार करें:
function Foo() {
this.data = 42,
document.body.onclick = this.method;
}
Foo.prototype.method = function() {
console.log(this.data);
};
समारोह this.methodके रूप में क्लिक करें ईवेंट हैंडलर असाइन किया गया है, लेकिन अगर document.bodyक्लिक किया जाता है, मूल्य लॉग इन किया जाएगा undefined, क्योंकि ईवेंट हैंडलर के अंदर, thisको संदर्भित करता है document.bodyकी, नहीं उदाहरण Foo।
जैसा कि शुरुआत में पहले ही उल्लेख किया गया है, जो इस thisबात पर निर्भर करता है कि फ़ंक्शन कैसे कहा जाता है , न कि इसे कैसे परिभाषित किया जाता है ।
यदि कोड निम्न जैसा था, तो यह अधिक स्पष्ट हो सकता है कि फ़ंक्शन में ऑब्जेक्ट का कोई निहित संदर्भ नहीं है:
function method() {
console.log(this.data);
}
function Foo() {
this.data = 42,
document.body.onclick = this.method;
}
Foo.prototype.method = method;
समाधान ऊपर उल्लिखित के समान है: यदि उपलब्ध हो, तो एक विशिष्ट मूल्य के .bindलिए स्पष्ट रूप से बांधने के thisलिए उपयोग करें
document.body.onclick = this.method.bind(this);
या फ़ंक्शन को कॉलबैक / ईवेंट हैंडलर के रूप में अनाम फ़ंक्शन का उपयोग करके या किसी thisअन्य चर के लिए ऑब्जेक्ट को "विधि" के रूप में स्पष्ट रूप से कॉल करें :
var self = this;
document.body.onclick = function() {
self.method();
};
या एक तीर फ़ंक्शन का उपयोग करें:
document.body.onclick = () => this.method();