"यह" कीवर्ड कैसे काम करता है?
मैंने देखा है कि this
स्टैक ओवरफ्लो साइट पर जावास्क्रिप्ट में उपयोग किया गया कीवर्ड क्या है और यह कैसे सही (और गलत तरीके से) है, इसकी स्पष्ट व्याख्या नहीं दिखाई देती है ।
मैंने इसके साथ कुछ बहुत ही अजीब व्यवहार देखा है और यह समझने में असफल रहा कि ऐसा क्यों हुआ है।
कैसे this
काम करता है और इसका उपयोग कब किया जाना चाहिए?
जवाब
मैं पहले जावास्क्रिप्ट ( दर्पण ) में माइक वेस्ट के लेख को पढ़ने की सलाह देता हूं । यह जावास्क्रिप्ट में अवधारणाओं और गुंजाइश श्रृंखलाओं का एक उत्कृष्ट, मैत्रीपूर्ण परिचय है ।this
एक बार जब आप अभ्यस्त होने लगते हैं this
, तो नियम वास्तव में बहुत सरल होते हैं। ECMAScript 5.1 स्टैंडर्ड परिभाषित करता है this
:
§11.1.1
this
कीवर्ड
this
वर्तमान निष्पादन संदर्भ से ThisBinding के मूल्य के कीवर्ड का मूल्यांकन
यह बाइंडिंग कुछ ऐसा है जो जावास्क्रिप्ट दुभाषिया बनाए रखता है क्योंकि यह जावास्क्रिप्ट कोड का मूल्यांकन करता है, जैसे एक विशेष सीपीयू रजिस्टर जो किसी वस्तु का संदर्भ रखता है। दुभाषिया जब भी केवल तीन अलग-अलग मामलों में एक निष्पादन संदर्भ स्थापित करता है, तो यह थिंकिंग अपडेट करता है:
1. प्रारंभिक वैश्विक निष्पादन संदर्भ
यह जावास्क्रिप्ट कोड के लिए मामला है जो शीर्ष-स्तर पर मूल्यांकन किया जाता है, उदाहरण के लिए जब सीधे अंदर <script>
:
<script>
alert("I'm evaluated in the initial global execution context!");
setTimeout(function () {
alert("I'm NOT evaluated in the initial global execution context.");
}, 1);
</script>
प्रारंभिक वैश्विक निष्पादन संदर्भ में कोड का मूल्यांकन करते समय, यह बंधन वैश्विक ऑब्जेक्ट पर सेट होता है, window
( .410.4.1.1 )।
2. eval कोड डालना
… इस
eval()
बाइंडिंग के लिए एक सीधी कॉल द्वारा अपरिवर्तित छोड़ दिया जाता है; यह कॉलिंग एक्ज़ीक्यूशन संदर्भ के थाइबिन्डिंग ( .210.4.2 (2) (a)) के समान है।… यदि इस प्रत्यक्ष
eval()
बंधन से कॉल नहीं होता है तो ग्लोबल ऑब्जेक्ट को वैश्विक वैश्विक निष्पादन संदर्भ ( execution10.4.2 (1)) में निष्पादित करते हुए सेट किया जाता है ।
§15.1.2.1.1 परिभाषित करता है कि प्रत्यक्ष कॉल क्या eval()
है। असल में, eval(...)
एक प्रत्यक्ष कॉल है जबकि कुछ ऐसा है (0, eval)(...)
या var indirectEval = eval; indirectEval(...);
एक अप्रत्यक्ष कॉल है eval()
। देखें chuckj का जवाब करने के लिए जावास्क्रिप्ट में eval ( 'इस') बनाम (1, eval) ( 'इस')? और दिमित्री सोशनिकोव के ईसीएमए -262-5 पर विस्तार से। अध्याय 2. सख्त मोड। जब आप एक अप्रत्यक्ष eval()
कॉल का उपयोग कर सकते हैं ।
3. फ़ंक्शन कोड दर्ज करना
यह एक फ़ंक्शन को कॉल करते समय होता है। यदि किसी फ़ंक्शन को किसी ऑब्जेक्ट पर, जैसे कि obj.myMethod()
या समतुल्य कहा जाता है obj["myMethod"]()
, तो ThisBinding ऑब्जेक्ट पर सेट होता है ( obj
उदाहरण में; example13.2.1 )। अधिकांश अन्य मामलों में, यह बाइंडिंग वैश्विक ऑब्जेक्ट ( .310.4.3 ) पर सेट है ।
"अधिकांश अन्य मामलों में" लिखने का कारण यह है कि वहाँ आठ ECMAScript 5 अंतर्निहित कार्य हैं जो तर्कों की सूची में इसबाइंडिंग को निर्दिष्ट करने की अनुमति देते हैं। ये विशेष कार्य एक तथाकथित लेते हैं thisArg
जो फ़ंक्शन को कॉल करते समय यह थिंकिंग बन जाता है ( .310.4.3 )।
ये विशेष अंतर्निहित कार्य हैं:
Function.prototype.apply( thisArg, argArray )
Function.prototype.call( thisArg [ , arg1 [ , arg2, ... ] ] )
Function.prototype.bind( thisArg [ , arg1 [ , arg2, ... ] ] )
Array.prototype.every( callbackfn [ , thisArg ] )
Array.prototype.some( callbackfn [ , thisArg ] )
Array.prototype.forEach( callbackfn [ , thisArg ] )
Array.prototype.map( callbackfn [ , thisArg ] )
Array.prototype.filter( callbackfn [ , thisArg ] )
Function.prototype
फ़ंक्शंस के मामले में , उन्हें एक फ़ंक्शन ऑब्जेक्ट पर कॉल किया जाता है, लेकिन फ़ंक्शन ऑब्जेक्ट के लिए इसबाइंडिंग को सेट करने के बजाय, यह बाइंडिंग को सेट किया जाता है thisArg
।
Array.prototype
कार्यों के मामले में , दिए गए callbackfn
को निष्पादन के संदर्भ में कहा जाता है जहां यह thisArg
आपूर्ति करने के लिए सेट किया गया है ; अन्यथा, वैश्विक वस्तु के लिए।
वे सादे जावास्क्रिप्ट के लिए नियम हैं। जब आप जावास्क्रिप्ट लाइब्रेरीज़ (जैसे jQuery) का उपयोग करना शुरू करते हैं, तो आप पा सकते हैं कि कुछ लाइब्रेरी फ़ंक्शंस मान में हेरफेर करते हैं this
। उन जावास्क्रिप्ट पुस्तकालयों के डेवलपर्स ऐसा करते हैं क्योंकि यह सबसे आम उपयोग के मामलों का समर्थन करता है, और पुस्तकालय के उपयोगकर्ता आमतौर पर इस व्यवहार को अधिक सुविधाजनक पाते हैं। जब this
लाइब्रेरी फ़ंक्शंस का संदर्भ देते हुए कॉलबैक फ़ंक्शंस पास करते हैं, तो आपको किसी भी गारंटी के लिए प्रलेखन का उल्लेख करना चाहिए this
कि फ़ंक्शन को कहा जाता है।
यदि आप सोच रहे हैं कि एक जावास्क्रिप्ट लाइब्रेरी किस तरह से मूल्य में हेरफेर करता है this
, तो लाइब्रेरी बस एक में निर्मित जावास्क्रिप्ट कार्यों में से एक का उपयोग करके स्वीकार कर रही है thisArg
। आप भी, कॉलबैक फ़ंक्शन लेने के लिए अपना स्वयं का फ़ंक्शन लिख सकते हैं और thisArg
:
function doWork(callbackfn, thisArg) {
//...
if (callbackfn != null) callbackfn.call(thisArg);
}
एक विशेष मामला है जिसका मैंने अभी तक उल्लेख नहीं किया है। new
ऑपरेटर के माध्यम से एक नई वस्तु का निर्माण करते समय , जावास्क्रिप्ट दुभाषिया एक नई, खाली वस्तु बनाता है, कुछ आंतरिक गुणों को सेट करता है, और फिर नए ऑब्जेक्ट पर कंस्ट्रक्टर फ़ंक्शन को कॉल करता है। इस प्रकार, जब एक फ़ंक्शन को एक कंस्ट्रक्टर संदर्भ में कहा जाता है, का मान this
नई वस्तु है जिसे इंटरप्रेटर बनाया जाता है:
function MyType() {
this.someData = "a string";
}
var instance = new MyType();
// Kind of like the following, but there are more steps involved:
// var instance = {};
// MyType.call(instance);
तीर कार्य
एरो फ़ंक्शंस (ECMA6 में पेश) के दायरे को बदल देते हैं this
। मौजूदा विहित प्रश्न, एरो फ़ंक्शन बनाम फ़ंक्शन घोषणा / अभिव्यक्तियाँ देखें: क्या वे समकक्ष / विनिमेय हैं? अधिक जानकारी के लिए। लेकिन संक्षेप में:
एरो फ़ंक्शंस के पास अपना नहीं है
this
.... बाध्यकारी। इसके बजाय, उन पहचानकर्ताओं को किसी अन्य चर की तरह शाब्दिक दायरे में हल किया जाता है। इसका मतलब है कि एक एरो फंक्शन के अंदर,this
... एरो फंक्शनthis
को एनवायरनमेंट के वैल्यूज में परिभाषित किया गया है।
बस मनोरंजन के लिए, कुछ उदाहरणों के साथ अपनी समझ का परीक्षण करें
उत्तरों को प्रकट करने के लिए, हल्के भूरे रंग के बक्सों पर माउस ले जाएँ।
this
चिह्नित लाइन पर मूल्य क्या है ? क्यों?
window
- प्रारंभिक वैश्विक निष्पादन संदर्भ में चिह्नित रेखा का मूल्यांकन किया जाता है।
if (true) {
// What is `this` here?
}
- निष्पादित
this
होने पर चिह्नित लाइन पर मूल्य क्या हैobj.staticFunction()
? क्यों?
obj
- किसी ऑब्जेक्ट पर फ़ंक्शन को कॉल करते समय, यह बाइंडिंग ऑब्जेक्ट पर सेट होता है।
var obj = {
someData: "a string"
};
function myFun() {
return this // What is `this` here?
}
obj.staticFunction = myFun;
console.log("this is window:", obj.staticFunction() == window);
console.log("this is obj:", obj.staticFunction() == obj);
this
चिह्नित लाइन पर मूल्य क्या है ? क्यों?
window
इस उदाहरण में, जावास्क्रिप्ट दुभाषिया फ़ंक्शन कोड में प्रवेश करता है, लेकिन क्योंकि
myFun
/obj.myMethod
किसी ऑब्जेक्ट पर नहीं बुलाया जाता है, यह बाइंडिंग सेट हैwindow
।यह पायथन से अलग है, जिसमें एक विधि (
obj.myMethod
) तक पहुंच एक बाध्य विधि ऑब्जेक्ट बनाता है ।
var obj = {
myMethod: function () {
return this; // What is `this` here?
}
};
var myFun = obj.myMethod;
console.log("this is window:", myFun() == window);
console.log("this is obj:", myFun() == obj);
this
चिह्नित लाइन पर मूल्य क्या है ? क्यों?
window
यह एक मुश्किल था। जब eval कोड का मूल्यांकन,
this
हैobj
। हालाँकि, eval कोड में,myFun
किसी ऑब्जेक्ट पर कॉल नहीं किया जाता है, इसलिए ThisBinding कोwindow
कॉल के लिए सेट किया गया है।
<!-- no snippet because, seemingly, eval doesn’t work in snippets -->
function myFun() {
return this; // What is `this` here?
}
var obj = {
myMethod: function () {
eval("myFun()");
}
};
this
चिह्नित लाइन पर मूल्य क्या है ? क्यों?
obj
लाइन
myFun.call(obj);
विशेष अंतर्निहित फ़ंक्शन का आह्वान कर रही हैFunction.prototype.call()
, जोthisArg
पहले तर्क के रूप में स्वीकार करता है।
function myFun() {
return this; // What is `this` here?
}
var obj = {
someData: "a string"
};
console.log("this is window:", myFun.call(obj) == window);
console.log("this is obj:", myFun.call(obj) == obj);
this
जावास्क्रिप्ट में अलग कीवर्ड बर्ताव करता है अन्य भाषाओं की तुलना में। ऑब्जेक्ट ओरिएंटेड भाषाओं में, this
कीवर्ड क्लास के वर्तमान उदाहरण को संदर्भित करता है। जावास्क्रिप्ट में मान को this
फ़ंक्शन के मंगलाचरण संदर्भ ( context.function()
) और जहां इसे कहा जाता है, द्वारा निर्धारित किया जाता है।
1. जब वैश्विक संदर्भ में उपयोग किया जाता है
जब आप this
वैश्विक संदर्भ में उपयोग करते हैं , तो यह वैश्विक ऑब्जेक्ट ( window
ब्राउज़र में) के लिए बाध्य है
document.write(this); //[object Window]
जब आप this
वैश्विक संदर्भ में परिभाषित फ़ंक्शन के अंदर उपयोग करते हैं , तब this
भी वैश्विक ऑब्जेक्ट के लिए बाध्य होता है क्योंकि फ़ंक्शन को वास्तव में वैश्विक संदर्भ का एक तरीका बनाया जाता है।
function f1()
{
return this;
}
document.write(f1()); //[object Window]
ऊपर f1
वैश्विक वस्तु का एक तरीका बनाया गया है। इस प्रकार हम इसे window
वस्तु के रूप में भी कह सकते हैं :
function f()
{
return this;
}
document.write(window.f()); //[object Window]
2. जब वस्तु विधि के अंदर प्रयोग किया जाता है
जब आप this
किसी ऑब्जेक्ट विधि के अंदर कीवर्ड का उपयोग करते हैं , तो ऑब्जेक्ट this
को "तत्काल" घेरने के लिए बाध्य होता है।
var obj = {
name: "obj",
f: function () {
return this + ":" + this.name;
}
};
document.write(obj.f()); //[object Object]:obj
ऊपर मैंने डबल कोट्स में तुरंत शब्द डाला है। यह बिंदु बनाना है कि यदि आप किसी अन्य ऑब्जेक्ट के अंदर ऑब्जेक्ट को घोंसले में डालते हैं, तो this
तत्काल माता-पिता के लिए बाध्य है।
var obj = {
name: "obj1",
nestedobj: {
name:"nestedobj",
f: function () {
return this + ":" + this.name;
}
}
}
document.write(obj.nestedobj.f()); //[object Object]:nestedobj
भले ही आप फ़ंक्शन को स्पष्ट रूप से ऑब्जेक्ट के लिए एक विधि के रूप में जोड़ते हैं, यह अभी भी नियमों से ऊपर है, जो this
अभी भी तत्काल मूल ऑब्जेक्ट की ओर इशारा करता है।
var obj1 = {
name: "obj1",
}
function returnName() {
return this + ":" + this.name;
}
obj1.f = returnName; //add method to object
document.write(obj1.f()); //[object Object]:obj1
3. जब संदर्भ-कम फ़ंक्शन को लागू करना
जब आप this
किसी भी संदर्भ (यानी किसी वस्तु पर नहीं) के बिना लागू किए गए फ़ंक्शन के अंदर का उपयोग करते हैं , तो यह वैश्विक ऑब्जेक्ट ( window
ब्राउज़र में) (भले ही फ़ंक्शन ऑब्जेक्ट के अंदर परिभाषित हो) के लिए बाध्य है ।
var context = "global";
var obj = {
context: "object",
method: function () {
function f() {
var context = "function";
return this + ":" +this.context;
};
return f(); //invoked without context
}
};
document.write(obj.method()); //[object Window]:global
सभी कार्यों के साथ यह कोशिश कर रहा है
हम कार्यों के साथ उपरोक्त बिंदुओं को भी आज़मा सकते हैं। हालाँकि कुछ अंतर हैं।
- ऊपर हमने ऑब्जेक्ट शाब्दिक संकेतन का उपयोग करके वस्तुओं में सदस्यों को जोड़ा। हम उपयोग करके कार्यों में सदस्यों को जोड़ सकते हैं
this
। उन्हें निर्दिष्ट करने के लिए। - ऑब्जेक्ट शाब्दिक अंकन वस्तु का एक उदाहरण बनाता है जिसे हम तुरंत उपयोग कर सकते हैं। फ़ंक्शन के साथ हमें पहले
new
ऑपरेटर का उपयोग करके इसकी आवृत्ति बनाने की आवश्यकता हो सकती है । - ऑब्जेक्ट शाब्दिक दृष्टिकोण में भी, हम डॉट ऑपरेटर का उपयोग करके स्पष्ट रूप से पहले से परिभाषित ऑब्जेक्ट में सदस्यों को जोड़ सकते हैं। यह केवल विशिष्ट उदाहरण में जोड़ा जाता है। हालाँकि मैंने फ़ंक्शन प्रोटोटाइप में चर जोड़ा है ताकि यह फ़ंक्शन के सभी उदाहरणों में परिलक्षित हो।
नीचे मैंने उन सभी चीजों को आज़माया जो हमने ऑब्जेक्ट और this
ऊपर के साथ किया था , लेकिन पहले सीधे ऑब्जेक्ट लिखने के बजाय फ़ंक्शन बनाकर।
/*********************************************************************
1. When you add variable to the function using this keyword, it
gets added to the function prototype, thus allowing all function
instances to have their own copy of the variables added.
*********************************************************************/
function functionDef()
{
this.name = "ObjDefinition";
this.getName = function(){
return this+":"+this.name;
}
}
obj1 = new functionDef();
document.write(obj1.getName() + "<br />"); //[object Object]:ObjDefinition
/*********************************************************************
2. Members explicitly added to the function protorype also behave
as above: all function instances have their own copy of the
variable added.
*********************************************************************/
functionDef.prototype.version = 1;
functionDef.prototype.getVersion = function(){
return "v"+this.version; //see how this.version refers to the
//version variable added through
//prototype
}
document.write(obj1.getVersion() + "<br />"); //v1
/*********************************************************************
3. Illustrating that the function variables added by both above
ways have their own copies across function instances
*********************************************************************/
functionDef.prototype.incrementVersion = function(){
this.version = this.version + 1;
}
var obj2 = new functionDef();
document.write(obj2.getVersion() + "<br />"); //v1
obj2.incrementVersion(); //incrementing version in obj2
//does not affect obj1 version
document.write(obj2.getVersion() + "<br />"); //v2
document.write(obj1.getVersion() + "<br />"); //v1
/*********************************************************************
4. `this` keyword refers to the immediate parent object. If you
nest the object through function prototype, then `this` inside
object refers to the nested object not the function instance
*********************************************************************/
functionDef.prototype.nestedObj = { name: 'nestedObj',
getName1 : function(){
return this+":"+this.name;
}
};
document.write(obj2.nestedObj.getName1() + "<br />"); //[object Object]:nestedObj
/*********************************************************************
5. If the method is on an object's prototype chain, `this` refers
to the object the method was called on, as if the method was on
the object.
*********************************************************************/
var ProtoObj = { fun: function () { return this.a } };
var obj3 = Object.create(ProtoObj); //creating an object setting ProtoObj
//as its prototype
obj3.a = 999; //adding instance member to obj3
document.write(obj3.fun()+"<br />");//999
//calling obj3.fun() makes
//ProtoObj.fun() to access obj3.a as
//if fun() is defined on obj3
4. जब कंस्ट्रक्टर फ़ंक्शन के अंदर उपयोग किया जाता है ।
जब फ़ंक्शन का उपयोग एक कंस्ट्रक्टर के रूप में किया जाता है (अर्थात जब इसे new
कीवर्ड के साथ कहा जाता है ), तो this
फ़ंक्शन बॉडी के अंदर नई ऑब्जेक्ट का निर्माण किया जाता है।
var myname = "global context";
function SimpleFun()
{
this.myname = "simple function";
}
var obj1 = new SimpleFun(); //adds myname to obj1
//1. `new` causes `this` inside the SimpleFun() to point to the
// object being constructed thus adding any member
// created inside SimipleFun() using this.membername to the
// object being constructed
//2. And by default `new` makes function to return newly
// constructed object if no explicit return value is specified
document.write(obj1.myname); //simple function
5. जब प्रोटोटाइप चेन पर परिभाषित फ़ंक्शन के अंदर उपयोग किया जाता है
यदि विधि किसी ऑब्जेक्ट की प्रोटोटाइप श्रृंखला पर है, तो this
इस तरह की विधि ऑब्जेक्ट को संदर्भित करती है विधि को बुलाया गया था, जैसे कि विधि को ऑब्जेक्ट पर परिभाषित किया गया है।
var ProtoObj = {
fun: function () {
return this.a;
}
};
//Object.create() creates object with ProtoObj as its
//prototype and assigns it to obj3, thus making fun()
//to be the method on its prototype chain
var obj3 = Object.create(ProtoObj);
obj3.a = 999;
document.write(obj3.fun()); //999
//Notice that fun() is defined on obj3's prototype but
//`this.a` inside fun() retrieves obj3.a
6. इनसाइड कॉल (), लागू () और बाइंड () फ़ंक्शन
- इन सभी तरीकों पर परिभाषित किया गया है
Function.prototype
। - ये विधियां एक बार एक फ़ंक्शन लिखने और इसे अलग-अलग संदर्भ में लागू करने की अनुमति देती हैं। दूसरे शब्दों में, वे उस मूल्य को निर्दिष्ट करने की अनुमति देते हैं
this
जिसका उपयोग तब किया जाएगा जब फ़ंक्शन निष्पादित किया जा रहा हो। यह मूल फ़ंक्शन को पारित करने के लिए किसी भी पैरामीटर को लेते हैं जब इसे लागू किया जाता है। fun.apply(obj1 [, argsArray])
अंदरobj1
के मूल्य के रूप में सेट करताthis
हैfun()
और इसके तर्कfun()
केargsArray
रूप में गुजर तत्वों को कॉल करता है।fun.call(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])
- अंदरobj1
के मूल्य के रूप में सेट करताthis
हैfun()
और इसके तर्कों के रूप मेंfun()
गुजरताarg1, arg2, arg3, ...
है।fun.bind(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])
- कार्य करने के लिए संदर्भ देता हैfun
के साथthis
अंदर मज़ा करने के लिए बाध्यobj1
और के मापदंडोंfun
निर्दिष्ट मापदंडों के लिए बाध्यarg1, arg2, arg3,...
।- अब के बीच का अंतर
apply
,call
औरbind
स्पष्ट हो गया होगा।apply
सरणी-समान ऑब्जेक्ट के रूप में कार्य करने के लिए तर्कों को निर्दिष्ट करने की अनुमति देता है अर्थात एक संख्यात्मकlength
संपत्ति और इसी गैर-नकारात्मक पूर्णांक गुणों के साथ एक वस्तु । जबकिcall
सीधे फ़ंक्शन को तर्कों को निर्दिष्ट करने की अनुमति देता है। दोनोंapply
औरcall
तुरंत निर्दिष्ट संदर्भ में और निर्दिष्ट तर्क के साथ समारोह का आह्वान। दूसरी ओर,bind
केवल निर्दिष्टthis
मान और तर्कों के लिए फ़ंक्शन को वापस लौटाता है। हम इसे लौटाए गए फ़ंक्शन के संदर्भ को एक चर में निर्दिष्ट करके कैप्चर कर सकते हैं और बाद में हम इसे किसी भी समय कॉल कर सकते हैं।
function add(inc1, inc2)
{
return this.a + inc1 + inc2;
}
var o = { a : 4 };
document.write(add.call(o, 5, 6)+"<br />"); //15
//above add.call(o,5,6) sets `this` inside
//add() to `o` and calls add() resulting:
// this.a + inc1 + inc2 =
// `o.a` i.e. 4 + 5 + 6 = 15
document.write(add.apply(o, [5, 6]) + "<br />"); //15
// `o.a` i.e. 4 + 5 + 6 = 15
var g = add.bind(o, 5, 6); //g: `o.a` i.e. 4 + 5 + 6
document.write(g()+"<br />"); //15
var h = add.bind(o, 5); //h: `o.a` i.e. 4 + 5 + ?
document.write(h(6) + "<br />"); //15
// 4 + 5 + 6 = 15
document.write(h() + "<br />"); //NaN
//no parameter is passed to h()
//thus inc2 inside add() is `undefined`
//4 + 5 + undefined = NaN</code>
7. this
घटना संचालकों के अंदर
- जब आप किसी तत्व के ईवेंट हैंडलर्स को सीधे फ़ंक्शन असाइन करते हैं, तो
this
सीधे ईवेंट हैंडलिंग फ़ंक्शन के अंदर का उपयोग संबंधित तत्व को संदर्भित करता है। इस तरह के प्रत्यक्ष कार्य असाइनमेंटaddeventListener
विधि का उपयोग करके या पारंपरिक इवेंट पंजीकरण विधियों जैसे के माध्यम से किया जा सकता हैonclick
। - इसी तरह, जब आप तत्व
this
की घटना संपत्ति (जैसे<button onclick="...this..." >
) के अंदर सीधे उपयोग करते हैं , तो यह तत्व को संदर्भित करता है। - हालाँकि
this
, ईवेंट हैंडलिंग फ़ंक्शन या ईवेंट प्रॉपर्टी के अंदर कहे गए अन्य फ़ंक्शन के माध्यम से अप्रत्यक्ष रूप से उपयोग वैश्विक ऑब्जेक्ट के लिए हल होता हैwindow
। - जब हम Microsoft के इवेंट पंजीकरण मॉडल विधि का उपयोग करके फ़ंक्शन हैंडलर को फ़ंक्शन से जोड़ते हैं, तो उपरोक्त व्यवहार प्राप्त किया जाता है
attachEvent
। ईवेंट हैंडलर को फ़ंक्शन असाइन करने के बजाय (और इस प्रकार तत्व की फ़ंक्शन विधि), यह फ़ंक्शन को ईवेंट पर कॉल करता है (प्रभावी रूप से इसे वैश्विक संदर्भ में कॉल करता है)।
मैं JSFiddle में बेहतर प्रयास करने की सलाह देता हूं ।
<script>
function clickedMe() {
alert(this + " : " + this.tagName + " : " + this.id);
}
document.getElementById("button1").addEventListener("click", clickedMe, false);
document.getElementById("button2").onclick = clickedMe;
document.getElementById("button5").attachEvent('onclick', clickedMe);
</script>
<h3>Using `this` "directly" inside event handler or event property</h3>
<button id="button1">click() "assigned" using addEventListner() </button><br />
<button id="button2">click() "assigned" using click() </button><br />
<button id="button3" onclick="alert(this+ ' : ' + this.tagName + ' : ' + this.id);">used `this` directly in click event property</button>
<h3>Using `this` "indirectly" inside event handler or event property</h3>
<button onclick="alert((function(){return this + ' : ' + this.tagName + ' : ' + this.id;})());">`this` used indirectly, inside function <br /> defined & called inside event property</button><br />
<button id="button4" onclick="clickedMe()">`this` used indirectly, inside function <br /> called inside event property</button> <br />
IE only: <button id="button5">click() "attached" using attachEvent() </button>
8. this
ES6 एरो फंक्शन में
एक तीर समारोह में, this
सामान्य चर की तरह व्यवहार करेंगे: यह अपने शाब्दिक दायरे से विरासत में मिलेगा। फ़ंक्शन का this
, जहां एरो फ़ंक्शन परिभाषित किया गया है, एरो फ़ंक्शन होगा this
।
तो, यह वही व्यवहार है:
(function(){}).bind(this)
निम्नलिखित कोड देखें:
const globalArrowFunction = () => {
return this;
};
console.log(globalArrowFunction()); //window
const contextObject = {
method1: () => {return this},
method2: function(){
return () => {return this};
}
};
console.log(contextObject.method1()); //window
const contextLessFunction = contextObject.method1;
console.log(contextLessFunction()); //window
console.log(contextObject.method2()()) //contextObject
const innerArrowFunction = contextObject.method2();
console.log(innerArrowFunction()); //contextObject
जावास्क्रिप्ट का 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
एस भी हैं 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
नेस्टेड-गुंजाइश मुद्दों को हल करने के लिए नकल ।
"यह" सभी गुंजाइश के बारे में है। हर फ़ंक्शन का अपना दायरा होता है, और जेएस में सब कुछ एक वस्तु है, यहां तक कि एक फ़ंक्शन भी "यह" का उपयोग करके कुछ मूल्यों को स्वयं में संग्रहीत कर सकता है। OOP 101 सिखाता है कि "यह" केवल एक वस्तु के उदाहरणों पर लागू होता है । इसलिए, हर बार जब कोई फ़ंक्शन निष्पादित होता है, तो उस फ़ंक्शन का एक नया "उदाहरण" "इस" का एक नया अर्थ होता है।
अनाम बंद कार्यों के अंदर "इस" का उपयोग करने की कोशिश करने पर अधिकांश लोग भ्रमित हो जाते हैं:
(फ़ंक्शन (मान) { this.value = value; $ ('। कुछ-तत्व')। प्रत्येक (फ़ंक्शन (elt) { elt.innerHTML = this.value; // उह ओह!! संभवतः अपरिभाषित }; }) (2);
तो यहाँ, प्रत्येक के अंदर (), "यह" उस "मूल्य" को नहीं रखता है जिसकी आप उससे (से) उम्मीद करते हैं
this.value = value;इसके ऊपर)। तो, इस (कोई दंडित इरादा नहीं) समस्या को खत्म करने के लिए, एक डेवलपर कर सकता है:
(फ़ंक्शन (मान) { var स्व = यह; // छोटा सा बदलाव self.value = value; $ ('। कुछ-तत्व')। प्रत्येक (फ़ंक्शन (elt) { elt.innerHTML = self.value; // भैया !! == २ }; }) (2);
कोशिश करके देखो; आपको प्रोग्रामिंग का यह पैटर्न पसंद आने लगेगा
चूंकि यह धागा टकरा गया है, इसलिए मैंने पाठकों के लिए नए this
विषय के लिए कुछ बिंदुओं को संकलित किया है ।
कैसे this
निर्धारित होता है मूल्य ?
हम इस तरह का उपयोग करते हैं, जैसे हम अंग्रेजी में प्राकृतिक भाषाओं में सर्वनाम का उपयोग करते हैं: "जॉन तेजी से भाग रहा है क्योंकि वह ट्रेन पकड़ने की कोशिश कर रहा है।" इसके बजाय हम लिख सकते थे “… जॉन ट्रेन पकड़ने की कोशिश कर रहा है”।
var person = {
firstName: "Penelope",
lastName: "Barrymore",
fullName: function () {
// We use "this" just as in the sentence above:
console.log(this.firstName + " " + this.lastName);
// We could have also written:
console.log(person.firstName + " " + person.lastName);
}
}
this
किसी मान को तब तक असाइन नहीं किया जाता है जब तक कोई ऑब्जेक्ट उस फ़ंक्शन को आमंत्रित नहीं करता है जहां वह परिभाषित है। वैश्विक दायरे में, सभी वैश्विक चर और कार्यों को window
ऑब्जेक्ट पर परिभाषित किया जाता है। इसलिए, this
एक वैश्विक फ़ंक्शन में वैश्विक window
ऑब्जेक्ट को संदर्भित करता है (और इसका मूल्य है) ।
जब use strict
, this
वैश्विक और अनाम कार्यों में, जो किसी भी वस्तु के लिए बाध्य नहीं हैं, का मूल्य होता है undefined
।
this
कीवर्ड है सबसे गलत समझा 1) हम एक विधि है कि का उपयोग करता है उधार: जब this
, 2) हम एक विधि है कि का उपयोग करता है आवंटित this
एक चर करने के लिए, 3) एक समारोह है कि का उपयोग करता है this
एक कॉलबैक समारोह के रूप में 4 पारित हो जाता है, और) this
को बंद करने के अंदर प्रयोग किया जाता है - एक आंतरिक कार्य। (२)
क्या भविष्य रखता है
ECMA स्क्रिप्ट 6 में परिभाषित , एरो-फ़ंक्शंस this
एन्कोडिंग (फ़ंक्शन या ग्लोबल) स्कोप से बाइंडिंग को गोद लेती है।
function foo() {
// return an arrow function
return (a) => {
// `this` here is lexically inherited from `foo()`
console.log(this.a);
};
}
var obj1 = { a: 2 };
var obj2 = { a: 3 };
var bar = foo.call(obj1);
bar.call( obj2 ); // 2, not 3!
हालांकि तीर-फ़ंक्शंस का उपयोग करने का एक विकल्प प्रदान करता है bind()
, यह ध्यान रखना महत्वपूर्ण है कि वे अनिवार्य रूप से पारंपरिक this
तंत्र को अधिक व्यापक रूप से समझने वाले लेक्सिकल स्कूपिंग के पक्ष में अक्षम कर रहे हैं । (1)
संदर्भ:
- इस और वस्तु प्रोटोटाइप , काइल सिम्पसन द्वारा। © 2014 Getify सॉल्यूशंस।
- javascriptissexy.com - http://goo.gl/pvl0GX
- एंगस ट्रोल - http://goo.gl/Z2RacU
this
जावास्क्रिप्ट में हमेशा उस फ़ंक्शन के 'स्वामी' को संदर्भित करता है जिसे निष्पादित किया जा रहा है ।
यदि कोई स्पष्ट स्वामी परिभाषित नहीं किया गया है, तो शीर्ष अधिकांश स्वामी, विंडो ऑब्जेक्ट, संदर्भित है।
तो अगर मैंने किया
function someKindOfFunction() {
this.style = 'foo';
}
element.onclick = someKindOfFunction;
this
तत्व वस्तु को संदर्भित करेगा। लेकिन सावधान रहें, बहुत सारे लोग यह गलती करते हैं।
<element onclick="someKindOfFunction()">
उत्तरार्द्ध मामले में, आप केवल फ़ंक्शन को संदर्भित करते हैं, इसे तत्व को नहीं सौंपते हैं। इसलिए, this
विंडो ऑब्जेक्ट को संदर्भित करेगा।
जावास्क्रिप्ट में प्रत्येक निष्पादन संदर्भ में इस पैरामीटर को सेट किया गया है:
- फ़ंक्शन कैसे कहा जाता है (ऑब्जेक्ट विधि के रूप में, कॉल का उपयोग करें और लागू करें, नए का उपयोग करें )
- बाँध का उपयोग
- तीर के कार्यों के लिए लेक्सिकली (वे अपने बाहरी निष्पादन के संदर्भ में इसे अपनाते हैं )
- चाहे कोड सख्त या गैर-सख्त मोड में हो
- क्या कोड का उपयोग करके लागू किया गया था eval
आप इस का उपयोग करके func.call
, func.apply
या का मान सेट कर सकते हैं func.bind
।
डिफ़ॉल्ट रूप से, और अधिकांश शुरुआती को क्या भ्रमित करता है, जब किसी श्रोता को एक DOM तत्व पर किसी ईवेंट के उठाए जाने के बाद बुलाया जाता है, तो फ़ंक्शन का यह मान DOM तत्व है।
jQuery jQuery.proxy के साथ बदलने के लिए इस तुच्छ बनाता है।
डैनियल, भयानक विवरण! इस पर शब्दों की एक जोड़ी और this
घटना संचालकों के मामले में निष्पादन संदर्भ सूचक की अच्छी सूची ।
दो शब्दों में, this
जावास्क्रिप्ट में उस वस्तु को इंगित किया गया है , जिससे (या जिसके निष्पादन संदर्भ से) वर्तमान फ़ंक्शन चलाया गया था और यह हमेशा केवल-पढ़ने के लिए है, आप इसे वैसे भी सेट नहीं कर सकते (ऐसा प्रयास 'अमान्य बाएं हाथ से समाप्त हो जाएगा' असाइनमेंट के संदेश में पक्ष।
ईवेंट हैंडलर के लिए: इनलाइन इवेंट हैंडलर, जैसे कि <element onclick="foo">
, पहले और पहले संलग्न किसी भी अन्य हैंडलर को ओवरराइड करते हैं, इसलिए सावधान रहें और इनलाइन इवेंट डेलिगेशन से दूर रहना बेहतर है। और ज़ारा अलावेर्डन का धन्यवाद जिन्होंने मुझे एक असंतोषपूर्ण बहस के माध्यम से उदाहरणों की इस सूची के लिए प्रेरित किया :)
el.onclick = foo; // in the foo - obj
el.onclick = function () {this.style.color = '#fff';} // obj
el.onclick = function() {doSomething();} // In the doSomething - Window
el.addEventListener('click',foo,false) // in the foo - obj
el.attachEvent('onclick, function () { // this }') // window, all the compliance to IE :)
<button onclick="this.style.color = '#fff';"> // obj
<button onclick="foo"> // In the foo - window, but you can <button onclick="foo(this)">
यहाँ का एक अच्छा स्रोत this
है JavaScript
।
यहाँ सारांश है:
यह वैश्विक है
एक ब्राउज़र में, वैश्विक क्षेत्र में,
this
हैwindow
वस्तु<script type="text/javascript"> console.log(this === window); // true var foo = "bar"; console.log(this.foo); // "bar" console.log(window.foo); // "bar"
उत्तर
node
का उपयोग करने में,this
शीर्ष नाम स्थान है। आप इसके रूप में संदर्भित कर सकते हैंglobal
।>this { ArrayBuffer: [Function: ArrayBuffer], Int8Array: { [Function: Int8Array] BYTES_PER_ELEMENT: 1 }, Uint8Array: { [Function: Uint8Array] BYTES_PER_ELEMENT: 1 }, ... >global === this true
में
node
एक स्क्रिप्ट से क्रियान्वित करने,this
वैश्विक क्षेत्र में एक खाली वस्तु के रूप में शुरू होता है। यह वैसा नहीं हैglobal
\\test.js console.log(this); \\ {} console.log(this === global); \\ fasle
यह कार्य करें
DOM ईवेंट हैंडलर के मामले में या जब thisArg
(प्रदान किया गया है और नीचे देखें) को छोड़कर , नोड और दोनों this
में एक फ़ंक्शन का उपयोग करने वाले ब्राउज़र में जिसे new
वैश्विक गुंजाइश के संदर्भ में नहीं कहा जाता है ...
<script type="text/javascript">
foo = "bar";
function testThis() {
this.foo = "foo";
}
console.log(this.foo); //logs "bar"
testThis();
console.log(this.foo); //logs "foo"
</script>
यदि आप उपयोग करते हैं use strict;
, तो किस मामले में this
होगाundefined
<script type="text/javascript">
foo = "bar";
function testThis() {
"use strict";
this.foo = "foo";
}
console.log(this.foo); //logs "bar"
testThis(); //Uncaught TypeError: Cannot set property 'foo' of undefined
</script>
यदि आप किसी फ़ंक्शन new
को this
वसीयत के साथ एक नया संदर्भ कहते हैं, तो यह वैश्विक संदर्भ नहीं होगा this
।
<script type="text/javascript">
foo = "bar";
function testThis() {
this.foo = "foo";
}
console.log(this.foo); //logs "bar"
new testThis();
console.log(this.foo); //logs "bar"
console.log(new testThis().foo); //logs "foo"
</script>
- यह प्रोटोटाइप
आपके द्वारा बनाए गए फ़ंक्शन फ़ंक्शन ऑब्जेक्ट बन जाते हैं। वे स्वचालित रूप से एक विशेष prototype
संपत्ति प्राप्त करते हैं, जो कुछ ऐसा है जिसे आप मान निर्दिष्ट कर सकते हैं। जब आप अपने फ़ंक्शन को कॉल करके एक उदाहरण बनाते हैं, तो आपको new
उन मानों तक पहुंच मिलती है जिन्हें आपने prototype
संपत्ति को सौंपा है । आप उन मूल्यों का उपयोग करते हैं this
।
function Thing() {
console.log(this.foo);
}
Thing.prototype.foo = "bar";
var thing = new Thing(); //logs "bar"
console.log(thing.foo); //logs "bar"
यह आमतौर पर आवंटित करने के लिए एक गलती है सरणियों या वस्तुओं पर prototype
। यदि आप चाहते हैं कि प्रत्येक के पास अपनी स्वयं की सरणियाँ हों, तो उन्हें फ़ंक्शन में बनाएँ, न कि प्रोटोटाइप में।
function Thing() {
this.things = [];
}
var thing1 = new Thing();
var thing2 = new Thing();
thing1.things.push("foo");
console.log(thing1.things); //logs ["foo"]
console.log(thing2.things); //logs []
- इस पर आपत्ति करें
आप this
किसी भी फ़ंक्शन में ऑब्जेक्ट पर अन्य गुणों को संदर्भित करने के लिए उपयोग कर सकते हैं । यह एक उदाहरण के साथ बनाया गया नहीं है new
।
var obj = {
foo: "bar",
logFoo: function () {
console.log(this.foo);
}
};
obj.logFoo(); //logs "bar"
- DOM ईवेंट
HTML DOM ईवेंट हैंडलर में, this
हमेशा DOM एलीमेंट का संदर्भ होता है, जिसमें ईवेंट अटैच किया गया था
function Listener() {
document.getElementById("foo").addEventListener("click",
this.handleClick);
}
Listener.prototype.handleClick = function (event) {
console.log(this); //logs "<div id="foo"></div>"
}
var listener = new Listener();
document.getElementById("foo").click();
जब तक आप bind
संदर्भ
function Listener() {
document.getElementById("foo").addEventListener("click",
this.handleClick.bind(this));
}
Listener.prototype.handleClick = function (event) {
console.log(this); //logs Listener {handleClick: function}
}
var listener = new Listener();
document.getElementById("foo").click();
- इसे HTML
HTML विशेषताओं के अंदर जिसमें आप जावास्क्रिप्ट डाल सकते हैं, this
तत्व का एक संदर्भ है।
<div id="foo" onclick="console.log(this);"></div>
<script type="text/javascript">
document.getElementById("foo").click(); //logs <div id="foo"...
</script>
- यह स्पष्ट करें
आप उपयोग eval
करने के लिए उपयोग कर सकते हैं this
।
function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
eval("console.log(this.foo)"); //logs "bar"
}
var thing = new Thing();
thing.logFoo();
- इसके साथ ही
आप स्पष्ट रूप से संदर्भित किए बिना मूल्यों को पढ़ने और लिखने के लिए वर्तमान दायरे में with
जोड़ने के this
लिए उपयोग कर सकते हैं ।this
this
function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
with (this) {
console.log(foo);
foo = "foo";
}
}
var thing = new Thing();
thing.logFoo(); // logs "bar"
console.log(thing.foo); // logs "foo"
- jQuery इस
jQuery के कई स्थानों में this
DOM तत्व का उल्लेख होगा।
<div class="foo bar1"></div>
<div class="foo bar2"></div>
<script type="text/javascript">
$(".foo").each(function () { console.log(this); //logs <div class="foo... }); $(".foo").on("click", function () {
console.log(this); //logs <div class="foo...
});
$(".foo").each(function () {
this.click();
});
</script>
जावास्क्रिप्ट में "इस" कीवर्ड की व्याख्या कैसे की जाती है, इस बारे में बहुत भ्रम है। उम्मीद है कि यह लेख उन सभी को एक बार और आराम करने के लिए रखेगा। और एक बहुत अधिक। कृपया पूरा लेख ध्यान से पढ़ें। इस लेख को लंबा है कि forewarned हो।
जिस संदर्भ में इसका उपयोग किया जाता है, उसके बावजूद, "यह" हमेशा जावास्क्रिप्ट में "वर्तमान वस्तु" का संदर्भ देता है। हालांकि, संदर्भ के अनुसार "वर्तमान वस्तु" क्या अलग है । संदर्भ वास्तव में हो सकता है 6 में से 1 निम्नलिखित:
- ग्लोबल (यानी सभी कार्यों के बाहर)
- डायरेक्ट "नॉन बाउंड फंक्शन" कॉल के अंदर (यानी एक फ़ंक्शन जिसे फ़ंक्शन फ़ंक्शन द्वारा बाध्य नहीं किया गया है। नाम )
- इनडायरेक्ट "नॉन बाउंड फंक्शन" के अंदर functionName.call और functionName.apply के माध्यम से कॉल करें
- "बाउंड फंक्शन" कॉल के अंदर (अर्थात एक फ़ंक्शन जिसे कॉल फ़ंक्शन द्वारा बाध्य किया गया है। Name.bind )
- जबकि वस्तु निर्माण "नया" के माध्यम से
- इनलाइन डोम इवेंट हैंडलर के अंदर
निम्नलिखित इस संदर्भ को एक-एक करके बताता है:
वैश्विक संदर्भ (यानी सभी कार्यों के बाहर):
सभी कार्यों के बाहर (यानी वैश्विक संदर्भ में) "वर्तमान वस्तु" (और इसलिए "यह" का मूल्य ) हमेशा ब्राउज़र के लिए "विंडो" ऑब्जेक्ट है।
डायरेक्ट "नॉन बाउंड फंक्शन" कॉल :
डायरेक्ट "नॉन बाउंड फंक्शन" कॉल के अंदर, फ़ंक्शन कॉल को लागू करने वाली वस्तु "वर्तमान वस्तु" बन जाती है (और इसलिए "यह" का मूल्य )। यदि किसी फ़ंक्शन को एक स्पष्ट वर्तमान ऑब्जेक्ट के बिना कहा जाता है , तो वर्तमान ऑब्जेक्ट या तो "विंडो" ऑब्जेक्ट (नॉन स्ट्रिक्ट मोड) या अपरिभाषित (फॉर स्ट्रिक्ट मोड) है। Global Context में परिभाषित कोई भी फ़ंक्शन (या वैरिएबल) स्वचालित रूप से "विंडो" ऑब्जेक्ट की एक संपत्ति बन जाता है। उदाहरण के लिए मान लीजिए कि फ़ंक्शन ग्लोबल संदर्भ में परिभाषित किया गया है
function UserDefinedFunction(){ alert(this) }
यह विंडो ऑब्जेक्ट की संपत्ति बन जाता है, जैसे कि आपने इसे परिभाषित किया है
window.UserDefinedFunction=function(){ alert(this) }
"गैर सख्त मोड" में, कॉलिंग / सीधे के माध्यम से इस समारोह लागू "() UserDefinedFunction" स्वचालित रूप से / यह आह्वान के रूप में कॉल करेंगे "window.UserDefinedFunction ()" बनाने "विंडो" के रूप में "वर्तमान वस्तु" (और इसलिए का मूल्य " यह " ) " UserDefinedFunction "के भीतर है। इस फ़ंक्शन को" नॉन स्ट्रिक्ट मोड "में बदलने पर निम्न परिणाम प्राप्त होंगे।
UserDefinedFunction() // displays [object Window] as it automatically gets invoked as window.UserDefinedFunction()
"सख्त मोड", कॉलिंग / सीधे के माध्यम से समारोह लागू में "UserDefinedFunction ()" होगा "नहीं" स्वचालित रूप से / यह आह्वान के रूप में फोन "window.UserDefinedFunction ()" .Hence "वर्तमान वस्तु" (और का मान "इस" ) "UserDefinedFunction" के भीतर अपरिभाषित किया जाएगा । इस फ़ंक्शन को "स्ट्रिक्ट मोड" में शामिल करने के परिणामस्वरूप निम्नलिखित होगा
UserDefinedFunction() // displays undefined
हालाँकि, विंडो ऑब्जेक्ट का उपयोग करके इसे स्पष्ट रूप से लागू करना निम्न में परिणाम होगा
window.UserDefinedFunction() // "always displays [object Window] irrespective of mode."
आइए हम एक और उदाहरण देखें। कृपया निम्नलिखित कोड देखें
function UserDefinedFunction() { alert(this.a + "," + this.b + "," + this.c + "," + this.d) } var o1={ a:1, b:2, f:UserDefinedFunction } var o2={ c:3, d:4, f:UserDefinedFunction } o1.f() // Shall display 1,2,undefined,undefined o2.f() // Shall display undefined,undefined,3,4
उपरोक्त उदाहरण में हम देखते हैं कि जब "UserDefinedFunction" को o1 के माध्यम से लागू किया गया था , तो "यह" O1 का मूल्य लेता है और इसके गुणों का मान "a" और "b" प्रदर्शित होता है। "सी" और "डी" के मूल्य को अपरिभाषित दिखाया गया था क्योंकि ओ 1 इन गुणों को परिभाषित नहीं करता है
इसी तरह जब "यूजरडिफाइंड फंक्शन" को ओ 2 के माध्यम से लागू किया गया था , "यह" ओ 2 का मूल्य लेता है और इसके गुणों का मूल्य "सी" और "डी" मिलता है। "ए" और "बी" के मूल्य को ओ 2 के रूप में अपरिभाषित दिखाया गया है। इन गुणों को परिभाषित नहीं करते।
अप्रत्यक्ष "नॉन बाउंड फंक्शन" के अंदर functionName.call और functionName.apply के माध्यम से कॉल करें :
जब एक "नॉन बाउंड फंक्शन" functionName.call या functionName.apply के माध्यम से कॉल किया जाता है , तो "वर्तमान ऑब्जेक्ट" (और इसलिए "यह" ) का मान "इस" पैरामीटर (पहला पैरामीटर) के मूल्य पर कॉल करने के लिए सेट किया गया है / आवेदन करें । निम्न कोड समान प्रदर्शित करता है।
function UserDefinedFunction() { alert(this.a + "," + this.b + "," + this.c + "," + this.d) } var o1={ a:1, b:2, f:UserDefinedFunction } var o2={ c:3, d:4, f:UserDefinedFunction } UserDefinedFunction.call(o1) // Shall display 1,2,undefined,undefined UserDefinedFunction.apply(o1) // Shall display 1,2,undefined,undefined UserDefinedFunction.call(o2) // Shall display undefined,undefined,3,4 UserDefinedFunction.apply(o2) // Shall display undefined,undefined,3,4 o1.f.call(o2) // Shall display undefined,undefined,3,4 o1.f.apply(o2) // Shall display undefined,undefined,3,4 o2.f.call(o1) // Shall display 1,2,undefined,undefined o2.f.apply(o1) // Shall display 1,2,undefined,undefined
उपरोक्त कोड स्पष्ट रूप से दिखाता है कि किसी भी "एनओएन बाउंड फंक्शन" के लिए "यह" मूल्य कॉल / आवेदन के माध्यम से बदला जा सकता है । इसके अलावा, अगर "इस" पैरामीटर को स्पष्ट रूप से कॉल / लागू करने के लिए पारित नहीं किया जाता है , तो "वर्तमान वस्तु" (और इसलिए "इस" का मूल्य) गैर-सख्त मोड में "विंडो" और सख्त मोड में "अपरिभाषित" पर सेट है।
"बाउंड फंक्शन" कॉल के अंदर (यानी एक फ़ंक्शन जिसे कॉल फ़ंक्शन द्वारा बाध्य किया गया है। Name.bind ):
एक बाउंड फ़ंक्शन एक फ़ंक्शन है जिसका "यह" मूल्य तय किया गया है। निम्न कोड यह दर्शाता है कि बाध्य फ़ंक्शन के मामले में "यह" कैसे काम करता है
function UserDefinedFunction() { alert(this.a + "," + this.b + "," + this.c + "," + this.d) } var o1={ a:1, b:2, f:UserDefinedFunction, bf:null } var o2={ c:3, d:4, f:UserDefinedFunction, bf:null } var bound1=UserDefinedFunction.bind(o1); // permanantly fixes "this" value of function "bound1" to Object o1 bound1() // Shall display 1,2,undefined,undefined var bound2=UserDefinedFunction.bind(o2); // permanantly fixes "this" value of function "bound2" to Object o2 bound2() // Shall display undefined,undefined,3,4 var bound3=o1.f.bind(o2); // permanantly fixes "this" value of function "bound3" to Object o2 bound3() // Shall display undefined,undefined,3,4 var bound4=o2.f.bind(o1); // permanantly fixes "this" value of function "bound4" to Object o1 bound4() // Shall display 1,2,undefined,undefined o1.bf=UserDefinedFunction.bind(o2) // permanantly fixes "this" value of function "o1.bf" to Object o2 o1.bf() // Shall display undefined,undefined,3,4 o2.bf=UserDefinedFunction.bind(o1) // permanantly fixes "this" value of function "o2.bf" to Object o1 o2.bf() // Shall display 1,2,undefined,undefined bound1.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function bound1.apply(o2) // Shall still display 1,2,undefined,undefined. "apply" cannot alter the value of "this" for bound function o2.bf.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function o2.bf.apply(o2) // Shall still display 1,2,undefined,undefined."apply" cannot alter the value of "this" for bound function
जैसा कि ऊपर दिए गए कोड में दिया गया है, किसी भी "बाउंड फंक्शन" के लिए यह "मूल्य" कॉल / आवेदन के माध्यम से नहीं बदला जा सकता है । इसके अलावा, अगर "इस" पैरामीटर को स्पष्ट रूप से बाँधने के लिए पारित नहीं किया गया है, तो "वर्तमान वस्तु" (और इसलिए "इस" का मूल्य ) गैर-सख्त मोड में "विंडो" और सख्त मोड में "अपरिभाषित" पर सेट है। एक बात और। पहले से ही बंधे फ़ंक्शन को बांधने से "यह" का मान नहीं बदलता है । यह पहले बाइंड फ़ंक्शन द्वारा निर्धारित मान के रूप में सेट रहता है।
जबकि वस्तु निर्माण "नए" के माध्यम से :
एक निर्माता फ़ंक्शन के अंदर, "वर्तमान ऑब्जेक्ट" (और इसलिए "इस" का मूल्य ) उस ऑब्जेक्ट को संदर्भित करता है जो वर्तमान में फ़ंक्शन की बाइंड स्थिति के "नए" के माध्यम से बनाया जा रहा है। हालाँकि, यदि निर्माता एक बाध्य फ़ंक्शन है, तो इसे बाध्य फ़ंक्शन के लिए पूर्वनिर्धारित सेट के साथ तर्कों के साथ बुलाया जाएगा।
इनलाइन डोम इवेंट हैंडलर के अंदर :
कृपया निम्नलिखित HTML स्निपेट देखें
<button onclick='this.style.color=white'>Hello World</button> <div style='width:100px;height:100px;' onclick='OnDivClick(event,this)'>Hello World</div>
"इस" में उपरोक्त उदाहरण क्रमशः "बटन" तत्व और "div" तत्व का संदर्भ लें।
पहले उदाहरण में, बटन का फ़ॉन्ट रंग सफ़ेद होने पर सेट किया जाएगा।
दूसरे उदाहरण में जब "div" तत्व को क्लिक किया जाता है, तो वह क्लिक किए गए div तत्व को संदर्भित करते हुए अपने दूसरे पैरामीटर के साथ OnDivClick फ़ंक्शन को कॉल करेगा । हालाँकि ऑनडिवक्लिक क्लिक के भीतर "यह" का मूल्य क्लिक किए गए div तत्व का संदर्भ नहीं देता है । इसे "विंडो ऑब्जेक्ट" या "अपरिभाषित" के रूप में क्रमशः गैर सख्त और सख्त मोड में सेट किया जाएगा (यदि ऑनडिवक्लिक एक अनबाउंड फ़ंक्शन है ) या पूर्वनिर्धारित मान पर सेट करें (यदि ऑनडिवक्लिक एक बाध्य फ़ंक्शन है )
निम्नलिखित पूरे लेख को सारांशित करता है
वैश्विक संदर्भ में "यह" हमेशा "विंडो" ऑब्जेक्ट को संदर्भित करता है
जब भी किसी कार्य का आह्वान किया जाता है, तो उसे किसी वस्तु ( "वर्तमान वस्तु" ) के संदर्भ में आमंत्रित किया जाता है । यदि वर्तमान वस्तु को स्पष्ट रूप से नहीं दी गई है, वर्तमान वस्तु है "खिड़की वस्तु" में गैर सख्त मोड और "अपरिभाषित" डिफ़ॉल्ट रूप से कठोर मोड में।
एक गैर बाउंड फंक्शन के भीतर "इस" का मान उस ऑब्जेक्ट के संदर्भ में है जिसके संदर्भ में फ़ंक्शन इंविक्ड किया गया है ( "वर्तमान ऑब्जेक्ट" )
एक गैर बाउंड फ़ंक्शन के भीतर "इस" का मान फ़ंक्शन के तरीकों को कॉल और लागू करने से अधिक हो सकता है।
"यह" का मान एक बाउंड फ़ंक्शन के लिए निर्धारित किया गया है और फ़ंक्शन के तरीकों को कॉल और लागू करने से अधिक नहीं हो सकता है ।
बाइंडिंग और पहले से ही बाध्य फ़ंक्शन "यह" का मूल्य नहीं बदलता है। यह पहले बाइंड फ़ंक्शन द्वारा निर्धारित मान के रूप में सेट रहता है।
एक निर्माता के भीतर "यह" का मूल्य वह वस्तु है जिसे बनाया और आरम्भ किया जा रहा है
इनलाइन DOM इवेंट हैंडलर के भीतर "इस" का मान उस तत्व का संदर्भ है जिसके लिए ईवेंट हैंडलर दिया गया है।
संभवतः सबसे विस्तृत और व्यापक लेख this
निम्नलिखित है:
जावास्क्रिप्ट में 'यह' कीवर्ड की कोमल व्याख्या
इसके पीछे this
का विचार यह समझना है कि फ़ंक्शन इनवोकेशन प्रकारों का this
मूल्य निर्धारण पर महत्वपूर्ण महत्व है ।
परेशानियों की पहचान करते समयthis
, खुद से न पूछें:
कहाँ से
this
लिया गया है ?
लेकिन है अपने आप से पूछना:
फ़ंक्शन को कैसे लागू किया जाता है ?
एरो फंक्शन (संदर्भ पारदर्शिता का विशेष मामला) के लिए खुद से पूछें:
this
तीर फ़ंक्शन को परिभाषित करने का क्या मूल्य है ?
इससे निपटने के दौरान यह मानसिकता सही है this
और आपको सिरदर्द से बचाएगा।
: यह सबसे अच्छा विवरण मैंने देखा है है JavaScripts समझे इस स्पष्टता के साथ
इस संदर्भ हमेशा के लिए संदर्भित करता है (और का मान रखती है), हालांकि यह वैश्विक क्षेत्र में एक समारोह के बाहर किया जा सकता है एक वस्तु एक विलक्षण वस्तु और यह आमतौर पर एक समारोह या एक विधि के अंदर किया जाता है। ध्यान दें कि जब हम सख्त मोड का उपयोग करते हैं, तो यह वैश्विक कार्यों और अपरिहार्य कार्यों में अपरिभाषित का मूल्य रखता है जो किसी भी वस्तु के लिए बाध्य नहीं हैं।
चार परिदृश्य हैं जहां यह भ्रमित हो सकता है:
- जब हम कॉलबैक फ़ंक्शन के रूप में उपयोग किए जाने वाले तर्क के रूप में एक विधि (जो इस का उपयोग करता है ) पास करते हैं।
- जब हम एक आंतरिक कार्य (एक बंद) का उपयोग करते हैं। यह ध्यान दें कि बंद बाहरी समारोह के उपयोग नहीं कर सकते रखना महत्वपूर्ण है यह इस कीवर्ड का उपयोग करके चर क्योंकि इस चर केवल समारोह अपने आप में पहुँचा जा सकता है, आंतरिक कार्यों के द्वारा नहीं।
- जब एक विधि जो इस पर निर्भर होती है उसे संदर्भों के एक चर को सौंपा जाता है, तो इस स्थिति में मूल रूप से इच्छित वस्तु की तुलना में किसी अन्य वस्तु को संदर्भित करता है।
- का उपयोग करते समय इस बाँध के साथ-साथ लागू होते हैं, और कॉल तरीके।
वह कोड उदाहरण, स्पष्टीकरण और समाधान देता है, जो मुझे लगा कि बहुत मददगार है।
this
जावास्क्रिप्ट में गलतफहमी अवधारणा में से एक है क्योंकि यह जगह से जगह पर थोड़ा अलग व्यवहार करता है। बस, उस फ़ंक्शनthis
के "मालिक" को संदर्भित करता है जिसे हम वर्तमान में निष्पादित कर रहे हैं ।
this
वर्तमान वस्तु (उर्फ निष्पादन संदर्भ) के साथ काम करने में मदद करता है। यदि आप समझते हैं कि वर्तमान फ़ंक्शन किस ऑब्जेक्ट में निष्पादित हो रहा है, तो आप आसानी से समझ सकते हैं कि वर्तमान क्या this
है
var val = "window.val"
var obj = {
val: "obj.val",
innerMethod: function () {
var val = "obj.val.inner",
func = function () {
var self = this;
return self.val;
};
return func;
},
outerMethod: function(){
return this.val;
}
};
//This actually gets executed inside window object
console.log(obj.innerMethod()()); //returns window.val
//Breakdown in to 2 lines explains this in detail
var _inn = obj.innerMethod();
console.log(_inn()); //returns window.val
console.log(obj.outerMethod()); //returns obj.val
ऊपर हम एक ही नाम 'वैल' के साथ 3 चर बनाते हैं। एक वैश्विक संदर्भ में, एक obj के अंदर और दूसरा obj के अंदरूनी हिस्से के अंदर। जावास्क्रिप्ट स्थानीय गो ग्लोबल से स्कोप चेन ऊपर जाकर एक विशेष संदर्भ में पहचानकर्ताओं को हल करती है।
कुछ ऐसी जगहें जहाँ पर विभेद this
किया जा सकता है
किसी वस्तु की विधि कहलाना
var status = 1;
var helper = {
status : 2,
getStatus: function () {
return this.status;
}
};
var theStatus1 = helper.getStatus(); //line1
console.log(theStatus1); //2
var theStatus2 = helper.getStatus;
console.log(theStatus2()); //1
जब लाइन 1 को निष्पादित किया जाता है, तो जावास्क्रिप्ट फ़ंक्शन कॉल के लिए एक निष्पादन संदर्भ (ईसी) स्थापित करता है, जो कि अंतिम से पहले आए ऑब्जेक्ट द्वारा संदर्भित ऑब्जेक्ट पर सेट this
होता है "।" । इसलिए अंतिम पंक्ति में आप समझ सकते हैं कि a()
वैश्विक संदर्भ में निष्पादित किया गया था जो कि है window
।
कंस्ट्रक्टर के साथ
this
बनाया जा रहा वस्तु को संदर्भित करने के लिए इस्तेमाल किया जा सकता है
function Person(name){
this.personName = name;
this.sayHello = function(){
return "Hello " + this.personName;
}
}
var person1 = new Person('Scott');
console.log(person1.sayHello()); //Hello Scott
var person2 = new Person('Hugh');
var sayHelloP2 = person2.sayHello;
console.log(sayHelloP2()); //Hello undefined
जब नया Person()
निष्पादित किया जाता है, तो एक पूरी तरह से नई वस्तु बनाई जाती है। Person
कहा जाता है और यह this
उस नई वस्तु को संदर्भित करने के लिए सेट है।
फंक्शन कॉल
function testFunc() {
this.name = "Name";
this.myCustomAttribute = "Custom Attribute";
return this;
}
var whatIsThis = testFunc();
console.log(whatIsThis); //window
var whatIsThis2 = new testFunc();
console.log(whatIsThis2); //testFunc() / object
console.log(window.myCustomAttribute); //Custom Attribute
यदि हम new
कीवर्ड को मिस करते हैं , whatIsThis
तो सबसे वैश्विक संदर्भ का संदर्भ देता है जो इसे पा सकता है ( window
)
घटना संचालकों के साथ
यदि ईवेंट हैंडलर इनलाइन है, तो this
वैश्विक ऑब्जेक्ट को संदर्भित करता है
<script type="application/javascript">
function click_handler() {
alert(this); // alerts the window object
}
</script>
<button id='thebutton' onclick='click_handler()'>Click me!</button>
जावास्क्रिप्ट के माध्यम से ईवेंट हैंडलर को जोड़ने पर, this
उस ईवेंट को उत्पन्न करने वाले DOM तत्व को संदर्भित करता है।
- तुम भी उपयोग कर संदर्भ में हेरफेर कर सकते हैं
.apply()
.call()
और.bind()
- JQuery प्रॉक्सी एक और तरीका है जिसका उपयोग आप यह सुनिश्चित करने के लिए कर सकते हैं कि फ़ंक्शन में यह आपकी इच्छा का मूल्य होगा। ( $ .Proxy समझें की जाँच करें ) , jQuery.proxy () उपयोग )
- var that = thisजावास्क्रिप्ट में क्या मतलब है
छद्मशास्त्रीय शब्दों में, जिस तरह से कई व्याख्यान 'इस' कीवर्ड को सिखाते हैं, एक वर्ग या ऑब्जेक्ट कंस्ट्रक्टर द्वारा त्वरित वस्तु के रूप में है। हर बार एक नई वस्तु का निर्माण एक वर्ग से किया जाता है, कल्पना करें कि हुड के तहत एक 'इस' वस्तु का एक स्थानीय उदाहरण बनाया और वापस किया जाता है। मुझे याद है यह इस तरह से पढ़ाया जाता है:
function Car(make, model, year) {
var this = {}; // under the hood, so to speak
this.make = make;
this.model = model;
this.year = year;
return this; // under the hood
}
var mycar = new Car('Eagle', 'Talon TSi', 1993);
// ========= under the hood
var this = {};
this.make = 'Eagle';
this.model = 'Talon TSi';
this.year = 1993;
return this;
"यह" का मान "संदर्भ" पर निर्भर करता है जिसमें फ़ंक्शन निष्पादित होता है। संदर्भ कोई भी वस्तु या वैश्विक वस्तु हो सकती है, अर्थात, खिड़की।
तो "यह" का शब्दार्थ पारंपरिक ओओपी भाषाओं से अलग है। और यह समस्याओं का कारण बनता है: 1. जब एक फ़ंक्शन दूसरे चर (सबसे अधिक संभावना है, एक कॉलबैक) को पारित किया जाता है; और 2. जब किसी वर्ग के सदस्य विधि से एक आह्वान किया जाता है।
दोनों ही मामलों में, यह विंडो पर सेट है।
यह किसकी मदद? (जावास्क्रिप्ट में 'इस' का अधिकांश भ्रम इस तथ्य से आ रहा है कि यह आम तौर पर आपकी वस्तु से जुड़ा नहीं है, लेकिन वर्तमान निष्पादन गुंजाइश के लिए - यह ठीक नहीं है कि यह कैसे काम करता है लेकिन हमेशा मुझे ऐसा लगता है - पूर्ण विवरण के लिए लेख देखें)
इस कीवर्ड के बारे में थोड़ी जानकारी
आइए this
किसी भी अधिक कोड के बिना वैश्विक दायरे में कीवर्ड को लॉग इन करें लेकिन
console.log(this)
में क्लाइंट / ब्राउज़र this
कीवर्ड एक वैश्विक वस्तु है जो हैwindow
console.log(this === window) // true
तथा
में सर्वर / नोड / जावास्क्रिप्ट क्रम this
कीवर्ड भी एक वैश्विक वस्तु है जो हैmodule.exports
console.log(this === module.exports) // true
console.log(this === exports) // true
ध्यान रखें कि exports
यह केवल एक संदर्भ हैmodule.exports
इस तरह से स्कोप के लिए इस का उपयोग करें
<script type="text/javascript" language="javascript">
$('#tbleName tbody tr').each(function{ var txt=''; txt += $(this).find("td").eq(0).text();
\\same as above but synatx different
var txt1='';
txt1+=$('#tbleName tbody tr').eq(0).text();
alert(txt1)
});
</script>
txt1 और txt का मूल्य उपरोक्त उदाहरण $ (यह) = $ ('# tbleName tbody tr') में समान है। समान है
मेरे पास this
उन अन्य उत्तरों से अलग है जो मुझे आशा है कि सहायक हैं।
जावास्क्रिप्ट को देखने का एक तरीका यह देखना है कि फ़ंक्शन 1 को कॉल करने का केवल 1 तरीका है । यह है
functionObject.call(objectForThis, arg0, arg1, arg2, ...);
हमेशा कुछ मूल्य दिया जाता है objectForThis
।
बाकी सब कुछ के लिए सिंथेटिक चीनी है functionObject.call
इसलिए, बाकी सभी चीजों का वर्णन किया जा सकता है कि यह किस प्रकार अनुवाद करता है functionObject.call
।
यदि आप केवल एक फ़ंक्शन कहते हैं, तो this
"वैश्विक ऑब्जेक्ट" है जो ब्राउज़र में विंडो है
function foo() {
console.log(this);
}
foo(); // this is the window object
दूसरे शब्दों में,
foo();
प्रभावी ढंग से अनुवाद किया गया था
foo.call(window);
ध्यान दें कि यदि आप सख्त मोड का उपयोग करते हैं तो this
होगाundefined
'use strict';
function foo() {
console.log(this);
}
foo(); // this is the window object
जिसका मतलब है
दूसरे शब्दों में,
foo();
प्रभावी ढंग से अनुवाद किया गया था
foo.call(undefined);
जावास्क्रिप्ट में तरह ऑपरेटरों देखते हैं +
और -
और *
। डॉट ऑपरेटर भी है जो है.
.
ऑपरेटर जब सही पर एक समारोह और छोड़ दिया पर एक वस्तु के साथ प्रयोग किया प्रभावी ढंग से "पास वस्तु के रूप में इसका मतलब है this
कार्य करने के लिए।
उदाहरण
const bar = {
name: 'bar',
foo() {
console.log(this);
},
};
bar.foo(); // this is bar
दूसरे शब्दों में bar.foo()
अनुवादconst temp = bar.foo; temp.call(bar);
ध्यान दें कि यह कोई फर्क नहीं पड़ता कि फ़ंक्शन कैसे बनाया गया था (ज्यादातर ...)। ये सभी एक ही परिणाम का उत्पादन करेंगे
const bar = {
name: 'bar',
fn1() { console.log(this); },
fn2: function() { console.log(this); },
fn3: otherFunction,
};
function otherFunction() { console.log(this) };
bar.fn1(); // this is bar
bar.fn2(); // this is bar
bar.fn3(); // this is bar
फिर से इन सभी के लिए बस वाक्य रचना चीनी हैं
{ const temp = bar.fn1; temp.call(bar); }
{ const temp = bar.fn2; temp.call(bar); }
{ const temp = bar.fn3; temp.call(bar); }
एक अन्य शिकन प्रोटोटाइप श्रृंखला है। जब आप a.b
जावास्क्रिप्ट का उपयोग करते हैं तो पहले a
संपत्ति के लिए सीधे संदर्भित ऑब्जेक्ट पर दिखता है b
। यदि b
ऑब्जेक्ट पर नहीं पाया जाता है, तो जावास्क्रिप्ट ऑब्जेक्ट के प्रोटोटाइप को खोजने के लिए दिखेगा b
।
किसी ऑब्जेक्ट के प्रोटोटाइप को परिभाषित करने के विभिन्न तरीके हैं, 2019 में सबसे आम class
कीवर्ड है। के प्रयोजनों के लिए this
हालांकि यह कोई फर्क नहीं पड़ता। क्या मायने रखता है कि जैसा कि यह a
संपत्ति के लिए वस्तु में दिखता है b
अगर यह b
वस्तु पर संपत्ति पाता है या यह प्रोटोटाइप श्रृंखला में है यदि b
एक फ़ंक्शन होता है तो उपरोक्त नियमों के समान ही लागू होता है। फ़ंक्शन b
संदर्भों को call
विधि का उपयोग करके कहा जाएगा और a
ऑब्जेक्टफॉर के रूप में पास किया जाएगा जैसा कि इस उत्तर के शीर्ष पर दिखाया गया है।
अब। आइए कल्पना करें कि हम एक फ़ंक्शन बनाते हैं जो स्पष्ट रूप this
से दूसरे फ़ंक्शन को कॉल करने से पहले सेट करता है और फिर इसे .
(डॉट) ऑपरेटर के साथ कॉल करता है
function foo() {
console.log(this);
}
function bar() {
const objectForThis = {name: 'moo'}
foo.call(objectForThis); // explicitly passing objectForThis
}
const obj = {
bar,
};
obj.bar();
उपयोग करने के लिए अनुवाद के बाद call
, obj.bar()
बन जाता है const temp = obj.bar; temp.call(obj);
। जब हम bar
फ़ंक्शन में प्रवेश करते हैं तो हम कॉल करते हैं foo
लेकिन हम ऑब्जेक्टफॉर के लिए किसी अन्य ऑब्जेक्ट में स्पष्ट रूप से पास हो जाते हैं, इसलिए जब हम फू पर पहुंचते हैं तो this
वह आंतरिक ऑब्जेक्ट होता है।
यह वही है जो दोनों कार्य करता है bind
और =>
प्रभावी ढंग से करता है। वे अधिक संश्लिष्ट चीनी हैं। वे प्रभावी रूप से एक नए अदृश्य फ़ंक्शन का निर्माण ठीक उसी तरह से bar
ऊपर करते हैं, जो स्पष्ट रूप से सेट करता है this
कि जो भी फ़ंक्शन निर्दिष्ट है। बाँध के मामले में this
आप जो भी पास करते हैं, उसके लिए निर्धारित है bind
।
function foo() {
console.log(this);
}
const bar = foo.bind({name: 'moo'});
// bind created a new invisible function that calls foo with the bound object.
bar();
// the objectForThis we are passing to bar here is ignored because
// the invisible function that bind created will call foo with with
// the object we bound above
bar.call({name: 'other'});
ध्यान दें कि यदि functionObject.bind
मौजूद नहीं था तो हम इस तरह से अपना खुद का बना सकते हैं
function bind(fn, objectForThis) {
return function(...args) {
return fn.call(objectForthis, ...args);
};
}
और फिर हम इसे इस तरह कह सकते हैं
function foo() {
console.log(this);
}
const bar = bind(foo, {name:'abc'});
एरो फ़ंक्शंस, =>
ऑपरेटर बाइंड के लिए सिंटैक्टिक शुगर है
const a = () => {console.log(this)};
के समान है
const tempFn = function() {console.log(this)};
const a = tempFn.bind(this);
जैसे bind
, एक नया अदृश्य फ़ंक्शन बनाया जाता है जो दिए गए फ़ंक्शन को एक बाध्य मान के साथ कॉल करता है, objectForThis
लेकिन bind
बाध्य होने वाली वस्तु के विपरीत है। यह this
तब होता है जब =>
ऑपरेटर का उपयोग किया जाता है।
तो, बस ऊपर दिए गए नियमों की तरह
const a = () => { console.log(this); } // this is the global object
'use strict';
const a = () => { console.log(this); } // this is undefined
function foo() {
return () => { console.log(this); }
}
const obj = {
foo,
};
const b = obj.foo();
b();
obj.foo()
const temp = obj.foo; temp.call(obj);
जिसका अनुवाद करने का अर्थ है कि तीर संचालक किसी नए अदृश्य फ़ंक्शन foo
से बंध जाएगा obj
और उस नए अदृश्य फ़ंक्शन को वापस लौटा देगा जिसे सौंपा गया है b
। b()
हमेशा की तरह काम करेगा b.call(window)
या बनाए b.call(undefined)
गए नए अदृश्य फ़ंक्शन को कॉल करेगा foo
। वह अदृश्य फ़ंक्शन इसमें this
पारित किए गए को अनदेखा करता है और obj
ऑब्जेक्ट फ़ंक्शन के रूप में गुजरता है ।
ऊपर दिया गया कोड अनुवाद करता है
function foo() {
function tempFn() {
console.log(this);
}
return tempFn.bind(this);
}
const obj = {
foo,
};
const b = obj.foo();
b.call(window or undefined if strict mode);
1 केapply
समान एक अन्य फ़ंक्शन हैcall
functionName.apply(objectForThis, arrayOfArgs);
लेकिन ईएस 6 के रूप में वैचारिक रूप से आप इसका अनुवाद भी कर सकते हैं
functionName.call(objectForThis, ...arrayOfArgs);
सारांश this
जावास्क्रिप्ट:
- के मान से
this
निर्धारित किया जाता है कि फ़ंक्शन को कैसे नहीं लगाया जाता है, जहां इसे बनाया गया था! - आमतौर पर का मान
this
उस वस्तु द्वारा निर्धारित किया जाता है जो डॉट से बची होती है। (window
वैश्विक अंतरिक्ष में) - ईवेंट श्रोताओं में
this
उस DOM तत्व को संदर्भित करता है जिस पर ईवेंट को बुलाया गया था। - जब फ़ंक्शन को
new
कीवर्ड के साथthis
नव निर्मित ऑब्जेक्ट को संदर्भित करता है का मान कहा जाता है - आप का मूल्य में हेरफेर कर सकते हैं
this
कार्यों के साथ:call
,apply
,bind
उदाहरण:
let object = {
prop1: function () {console.log(this);}
}
object.prop1(); // object is left of the dot, thus this is object
const myFunction = object.prop1 // We store the function in the variable myFunction
myFunction(); // Here we are in the global space
// myFunction is a property on the global object
// Therefore it logs the window object
उदाहरण घटना श्रोता:
document.querySelector('.foo').addEventListener('click', function () {
console.log(this); // This refers to the DOM element the eventListener was invoked from
})
document.querySelector('.foo').addEventListener('click', () => {
console.log(this); // Tip, es6 arrow function don't have their own binding to the this v
}) // Therefore this will log the global object
.foo:hover {
color: red;
cursor: pointer;
}
<div class="foo">click me</div>
उदाहरण निर्माता:
function Person (name) {
this.name = name;
}
const me = new Person('Willem');
// When using the new keyword the this in the constructor function will refer to the newly created object
console.log(me.name);
// Therefore, the name property was placed on the object created with new keyword.
"यह" ठीक से समझने के लिए किसी को उनके बीच के संदर्भ और दायरे और अंतर को समझना चाहिए।
स्कोप : जावास्क्रिप्ट दायरे में चर की दृश्यता से संबंधित है, फ़ंक्शन के उपयोग के माध्यम से गुंजाइश प्राप्त होती है। (दायरे के बारे में और पढ़ें)
संदर्भ : संदर्भ वस्तुओं से संबंधित है। यह उस वस्तु को संदर्भित करता है जिससे कोई फ़ंक्शन संबंधित है। जब आप जावास्क्रिप्ट "इस" कीवर्ड का उपयोग करते हैं, तो यह उस ऑब्जेक्ट को संदर्भित करता है जो किस फ़ंक्शन से संबंधित है। उदाहरण के लिए, किसी फ़ंक्शन के अंदर, जब आप कहते हैं: "this.accoutNumber", आप उस संपत्ति "accoutNumber" का उल्लेख कर रहे हैं, जो उस फ़ंक्शन के ऑब्जेक्ट से संबंधित है।
यदि ऑब्जेक्ट "myObj" में "getMyName" नामक एक विधि है, जब जावास्क्रिप्ट कीवर्ड "this" का उपयोग "getMyName" के अंदर किया जाता है, तो यह "myObj" को संदर्भित करता है। यदि फ़ंक्शन "getMyName" को वैश्विक दायरे में निष्पादित किया गया था, तो "यह" विंडो ऑब्जेक्ट (सख्त मोड को छोड़कर) को संदर्भित करता है।
अब कुछ उदाहरण देखते हैं:
<script>
console.log('What is this: '+this);
console.log(this);
</script>
ब्राउज़र आउटपुट में रननिग एबोव कोड होगा:
आउटपुट के अनुसार आप विंडो ऑब्जेक्ट के संदर्भ में हैं, यह भी दिखाई देता है कि विंडो प्रोटोटाइप ऑब्जेक्ट को संदर्भित करता है।
अब एक फंक्शन के अंदर कोशिश करते हैं:
<script>
function myFunc(){
console.log('What is this: '+this);
console.log(this);
}
myFunc();
</script>
आउटपुट:
अब हम अपनी वस्तु बनाते हैं। जावास्क्रिप्ट में, आप कई तरह से एक ऑब्जेक्ट बना सकते हैं।
<script>
var firstName = "Nora";
var lastName = "Zaman";
var myObj = {
firstName:"Lord",
lastName:'Baron',
printNameGetContext:function(){
console.log(firstName + " "+lastName);
console.log(this.firstName +" "+this.lastName);
return this;
}
}
var context = myObj.printNameGetContext();
console.log(context);
</script>
आउटपुट:
इसलिए उपरोक्त उदाहरण से, हमने पाया कि 'यह' कीवर्ड एक नए संदर्भ का संदर्भ दे रहा है जो myObj से संबंधित है, और myObject में प्रोटोटाइप चेन टू ऑब्जेक्ट भी है।
चलो एक और उदाहरण फेंकते हैं:
<body>
<button class="btn">Click Me</button>
<script>
function printMe(){
//Terminal2: this function declared inside window context so this function belongs to the window object.
console.log(this);
}
document.querySelector('.btn').addEventListener('click', function(){
//Terminal1: button context, this callback function belongs to DOM element
console.log(this);
printMe();
})
</script>
</body>
आउटपुट: सही समझ में आता है? (टिप्पणी पढ़ें)
यदि आपको उपरोक्त उदाहरण को समझने में परेशानी हो रही है तो आइए अपने स्वयं के कॉलबैक के साथ प्रयास करें;
<script>
var myObj = {
firstName:"Lord",
lastName:'Baron',
printName:function(callback1, callback2){
//Attaching callback1 with this myObj context
this.callback1 = callback1;
this.callback1(this.firstName +" "+this.lastName)
//We did not attached callback2 with myObj so, it's reamin with window context by default
callback2();
/*
//test bellow codes
this.callback2 = callback2;
this.callback2();
*/
}
}
var callback2 = function (){
console.log(this);
}
myObj.printName(function(data){
console.log(data);
console.log(this);
}, callback2);
</script>
आउटपुट:
अब आइए समझें स्कोप, स्व, आईआईएफई और यह कैसे व्यवहार करता है
var color = 'red'; // property of window
var obj = {
color:'blue', // property of window
printColor: function(){ // property of obj, attached with obj
var self = this;
console.log('In printColor -- this.color: '+this.color);
console.log('In printColor -- self.color: '+self.color);
(function(){ // decleard inside of printColor but not property of object, it will executed on window context.
console.log(this)
console.log('In IIFE -- this.color: '+this.color);
console.log('In IIFE -- self.color: '+self.color);
})();
function nestedFunc(){// decleard inside of printColor but not property of object, it will executed on window context.
console.log('nested fun -- this.color: '+this.color);
console.log('nested fun -- self.color: '+self.color);
}
nestedFunc(); // executed on window context
return nestedFunc;
}
};
obj.printColor()(); // returned function executed on window context
</script>
आउटपुट बहुत बढ़िया सही है?