जावास्क्रिप्ट का 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कीवर्ड का उपयोग करते हैं तो क्या होता है ।
newकीवर्ड के साथ फ़ंक्शन को कॉल करना तुरंत एक Objectप्रकार का प्रारंभ करेगा Person।
- इसके निर्माण के लिए
Objectइसके निर्माता ने निर्धारित किया है Person। इसके अलावा, ध्यान दें कि केवल typeof awalवापस आ जाएगा Object।
- इस नए
Objectको का प्रोटोटाइप सौंपा जाएगा Person.prototype। इसका मतलब यह है कि Personप्रोटोटाइप में कोई भी तरीका या संपत्ति सभी उदाहरणों के लिए उपलब्ध होगी Person, जिसमें शामिल हैं awal।
- फ़ंक्शन
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। चतुर, एह?
सूचकांक:
thisडिफ़ॉल्ट रूप से क्या आयोजित किया जाता है?
- क्या होगा यदि हम फ़ंक्शन को ऑब्जेक्ट-डॉट नोटेशन के साथ एक विधि के रूप में कहते हैं?
- यदि हम
newकीवर्ड का उपयोग करते हैं तो क्या होगा ?
- हम कैसे और के
thisसाथ हेरफेर करते हैं ?callapply
- का उपयोग कर
bind।
thisनेस्टेड-गुंजाइश मुद्दों को हल करने के लिए नकल ।