जावास्क्रिप्ट का 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
सहित )। उदाहरण के लिए निम्न कोड लें।Array
Function
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
तो हाँ, चूँकि function
s 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
साथ हेरफेर करते हैं ?call
apply
- का उपयोग कर
bind
।
this
नेस्टेड-गुंजाइश मुद्दों को हल करने के लिए नकल ।