- अॅरो फंक्शन्स एक संक्षिप्त वाक्यरचना आणि कॅप्चर प्रदान करतात
thisस्वतःचे बंधन निर्माण करण्याऐवजी, त्यांच्या सभोवतालच्या व्याप्तीतून शब्दशः. - च्या मूल्य
thisनियमित फंक्शन्समध्ये ते कसे म्हणतात यावर अवलंबून असते, जे फंक्शन्स, मेथड्स, कन्स्ट्रक्टर्स, क्लासेस आणि कॉलबॅक्सवर परिणाम करते. - कॉलबॅक आणि अॅरे पद्धतींसाठी अॅरो फंक्शन्स आदर्श आहेत, परंतु ऑब्जेक्ट पद्धती, DOM इव्हेंट हँडलर्स आणि कन्स्ट्रक्टरसाठी ते एक वाईट पर्याय आहेत.
- कधी समजून घेणे
thisसूक्ष्म दोष टाळण्यासाठी आणि बाण आणि पारंपारिक फंक्शन्समधून निवड करण्यासाठी डायनॅमिक विरुद्ध लेक्सिकल हे आवश्यक आहे.
जर तुम्ही कधी लॉग इन केले असेल तर this वेगवेगळ्या जावास्क्रिप्ट फंक्शन्समध्ये आणि खूपच वेगळे परिणाम मिळाले, तुम्ही एकटे नाही आहात. अनेक डेव्हलपर्सना अशा प्रकरणांमध्ये जावे लागते जिथे एखादी पद्धत अपेक्षित ऑब्जेक्ट प्रिंट करते, तर एक अॅरो फंक्शन प्रिंट करते window, आणि अचानक एक नेस्टेड बाण "जादुईपणे" आजूबाजूच्या ऑब्जेक्टकडे निर्देशित करतो. असे का घडते हे समजून घेणे ही अंदाजे, बग-मुक्त कोड लिहिण्याची गुरुकिल्ली आहे.
बाण फंक्शन्स आणि this कीवर्ड हा आधुनिक जावास्क्रिप्टमधील सर्वात महत्वाच्या (आणि गैरसमज असलेल्या) संयोजनांपैकी एक आहे. अॅरो फंक्शन्स फक्त एका लहान वाक्यरचनासारखे दिसतात, परंतु हुड अंतर्गत ते कसे बदलतात this हाताळले जाते, कॉलबॅक कसे वागतात आणि तुम्ही त्यांचा वापर पद्धती म्हणून कधी करावा किंवा करू नये हे देखील. चला वाक्यरचनापासून अंमलबजावणीच्या संदर्भापर्यंत, साध्या इंग्रजी आणि अनेक व्यावहारिक उदाहरणांचा वापर करून, टप्प्याटप्प्याने सर्वकाही पाहू.
गोंधळाशिवाय अॅरो फंक्शन सिंटॅक्स
अॅरो फंक्शन्स म्हणजे फंक्शन एक्सप्रेशन्स जे यासह लिहिलेले असतात => च्या ऐवजी वाक्यरचना function कीवर्ड. संकल्पनात्मकदृष्ट्या, तुम्ही त्यांना लिहिण्याचा एक संक्षिप्त मार्ग म्हणून विचार करू शकता: "हे पॅरामीटर्स घ्या, या अभिव्यक्तीचे किंवा कोडच्या ब्लॉकचे मूल्यांकन करा आणि मूल्य परत करा." खाली, ते अजूनही फंक्शन्स आहेत, परंतु ते अनेक महत्त्वाच्या मार्गांनी वेगळ्या पद्धतीने वागतात.
सर्वात मूलभूत बाण फंक्शन थेट नियमित फंक्शन अभिव्यक्तीशी मॅप करते. उदाहरणार्थ, ही क्लासिक फंक्शन एक्सप्रेशन:
const multiplyByTwo = function (value) { return value * 2; };
बाण फंक्शन म्हणून याप्रमाणे पुन्हा लिहिता येते:
const multiplyByTwo = (value) => { return value * 2; };
जेव्हा शरीर एकच अभिव्यक्ती असते तेव्हा बाणाची कार्ये चमकतात. जर बॉडी फक्त एकच स्टेटमेंट असेल जे काहीतरी परत करते, तर तुम्ही कर्ली ब्रेसेस आणि एक्सप्लिसिट दोन्ही वगळू शकता. return, अंतर्निहित परतावा सक्षम करणे:
const multiplyByTwo = value => value * 2;
जेव्हा अगदी एकच पॅरामीटर असेल तेव्हा तुम्ही आजूबाजूचे कंस वगळू शकता, परंतु फक्त त्या विशिष्ट बाबतीत. So x => x * 2 वैध आहे, परंतु जर तुमच्याकडे शून्य किंवा अनेक पॅरामीटर्स असतील तर तुम्ही कंस ठेवणे आवश्यक आहे:
- शून्य पॅरामीटर्स:
() => 42 - एक पॅरामीटर:
x => x * 2or(x) => x * 2 - दोन किंवा अधिक पॅरामीटर्स:
(x, y) => x + y
जेव्हा तुम्हाला बॉडीमध्ये एकापेक्षा जास्त स्टेटमेंटची आवश्यकता असेल, तेव्हा तुम्ही कर्ली ब्रेसेस आणि एक स्पष्ट return. त्या परिस्थितीत, रिटर्नच्या बाबतीत बाण फंक्शन्स नियमित फंक्शन्ससारखे वागतात: नाही. return, कोणतेही मूल्य परत मिळाले नाही.
const feedCat = (status) => {
if (status === 'hungry') {
return 'Feed the cat';
} else {
return 'Do not feed the cat';
}
};
अॅरो फंक्शन्समधून ऑब्जेक्ट लिटरल्स परत करताना काळजी घ्या, कारण ऑब्जेक्टचे ब्रेसेस फंक्शन बॉडीशी गोंधळले जाऊ शकतात. ती अस्पष्टता टाळण्यासाठी, ऑब्जेक्ट लिटरल कंसात गुंडाळा जेणेकरून जावास्क्रिप्टला कळेल की ते परत करायचे एक्सप्रेशन आहे:
const toObject = value => ({ result: value });
आणखी एक गोष्ट: बाण फंक्शन्स नेहमीच अभिव्यक्ती असतात, कधीही घोषणा नसतात. याचा अर्थ त्यांना एखाद्या चल, गुणधर्माला नियुक्त केले पाहिजे किंवा युक्तिवाद म्हणून पास केले पाहिजे; ते एकटे उभे राहू शकत नाहीत जसे function myFunc() {}, आणि ते फंक्शन डिक्लेरेशन प्रमाणेच फडकवले जात नाहीत, म्हणून ते परिभाषित होण्यापूर्वी तुम्ही त्यांना कॉल करू शकत नाही.
नक्की काय आहे this जावास्क्रिप्ट मध्ये?
कीवर्ड this हे एक डायनॅमिक बाइंडिंग आहे जे जावास्क्रिप्ट तुमच्यासाठी एखादे फंक्शन किंवा क्लास मेथड कार्यान्वित करते तेव्हा तयार करते. तुम्ही ते एका अदृश्य पॅरामीटर म्हणून विचार करू शकता ज्याचे मूल्य फंक्शन कसे आणि कुठे कॉल केले जाते यावर अवलंबून असते. यामुळे ते शक्तिशाली आणि लवचिक बनते, परंतु गोंधळाचे एक मोठे कारण देखील बनते.
कठोर नसलेल्या कार्यात, this नेहमी कोणत्या ना कोणत्या ऑब्जेक्टवर अवलंबून असते; स्ट्रिक्ट मोडमध्ये ते अक्षरशः कोणतेही मूल्य असू शकते, ज्यामध्ये undefined. जावास्क्रिप्ट एक्झिक्युशन संदर्भाच्या आधारावर ते मूल्य ठरवते: रेग्युलर फंक्शन, मेथड कॉल, कन्स्ट्रक्टर कॉल, क्लास, ग्लोबल स्कोप किंवा अॅरो फंक्शन.
क्लासिक स्क्रिप्टच्या वरच्या पातळीवर (मॉड्यूल नाही), this बोलणे globalThis, जे सहसा ब्राउझरचे असते window ऑब्जेक्ट. तर ब्राउझरमध्ये खालील तुलना खरी असेल:
console.log(this === window); // true
बाण नसलेल्या फंक्शन्समध्ये, this पूर्णपणे कॉल साइटद्वारे निश्चित केले जाते. जर तुम्ही फोन केला तर obj.method(), नंतर आत method चे मूल्य this is obj. जर तुम्ही तेच फंक्शन घेतले आणि त्याला स्टँडअलोन असे म्हटले तर fn() कडक मोडमध्ये, this होते undefined; नॉन-स्ट्रिक्ट मोडमध्ये, जावास्क्रिप्ट "बदलते" this सह globalThis.
महत्त्वाचे म्हणजे, फंक्शन कुठे परिभाषित केले आहे हे महत्त्वाचे नाही, तर ते कसे म्हटले जाते हे महत्त्वाचे आहे. एखादी पद्धत प्रोटोटाइप साखळीवर राहू शकते किंवा वेगळ्या ऑब्जेक्टला पुन्हा नियुक्त केली जाऊ शकते आणि तरीही ती पाहू शकते this कॉल वेळेत प्रत्यक्षात वापरल्या जाणाऱ्या कोणत्याही ऑब्जेक्टप्रमाणे. एखादी पद्धत पास केल्याने अनेकदा त्याचे स्वरूप बदलते. this जोपर्यंत तुम्ही ते स्पष्टपणे दुरुस्त करत नाही.
नियंत्रित करण्यासाठी साधने देखील आहेत this स्पष्टपणे: call, apply, bindआणि Reflect.apply. हे तुम्हाला हवे असलेले "इंजेक्ट" करू देतात this मूल्य: fn.call(obj, arg1, arg2) अंमलात आणेल fn सह this वर सेट obj. नॉन-स्ट्रिकट मोडमध्येही समान बदली नियम लागू होतात: जर तुम्ही उत्तीर्ण झालात तर null or undefined as this, त्यांची जागा घेतली जाते globalThis; आदिम त्यांच्या आवरणाच्या वस्तूंमध्ये बॉक्समध्ये अडकतात.
कॉलबॅकमुळे अप्रत्यक्षतेचा आणखी एक थर जोडला जातो, कारण this तुमच्या कॉलबॅकवर कॉल करणाऱ्या व्यक्तीद्वारे नियंत्रित केले जाते. अॅरे पुनरावृत्ती पद्धती, Promise कन्स्ट्रक्टर आणि तत्सम API सहसा कॉलबॅक कॉल करतात this वर सेट undefined (किंवा स्लोपी मोडमधील ग्लोबल ऑब्जेक्ट). काही एपीआय, जसे की Array.prototype.forEach or Set.prototype.forEach, वेगळा स्वीकारा thisArg कॉलबॅक सेट करण्यासाठी तुम्ही वापरू शकता असा पॅरामीटर this.
इतर API जाणूनबुजून कस्टमसह कॉलबॅक कॉल करतात this मूल्ये. उदाहरणार्थ, अगोदर निर्देश केलेल्या बाबीसंबंधी बोलताना reviver युक्तिवाद JSON.parse आणि ते replacer साठी JSON.stringify प्राप्त this सध्या प्रक्रिया केली जात असलेल्या मालमत्तेच्या मालकीच्या ऑब्जेक्टशी बांधलेले. DOM मधील इव्हेंट हँडलर "क्लासिक" पद्धतीने लिहिताना ते ज्या घटकाशी जोडलेले असतात त्या घटकाशी बांधलेले असतात.
मूळ कल्पना: बाण फंक्शन्स स्वतःचे तयार करत नाहीत this
बाण फंक्शन्सचे परिभाषित वैशिष्ट्य म्हणजे ते कधीही नवीन तयार करत नाहीत this बंधनकारक. त्याऐवजी, ते बंद करतात (किंवा "कॅप्चर" करतात) this जेव्हा ते तयार होतात तेव्हा आजूबाजूच्या शब्दावली वातावरणातून. जेव्हा बाण नंतर कार्यान्वित होतो, तेव्हा तो फक्त त्या कॅप्चर केलेल्या मूल्याचा पुनर्वापर करतो, तुम्ही त्याला कसेही म्हणा.
प्रत्यक्षात, एक बाण फंक्शन असे वागते की ते कायमचे स्वयंचलितपणे जोडलेले असते this त्याच्या बाह्य व्याप्तीचा. म्हणूनच पद्धती जसे की call, applyआणि bind बदलू शकत नाही this बाण फंक्शनसाठी: thisArg युक्तिवादाकडे दुर्लक्ष केले जाते. तुम्ही अजूनही त्यांच्याद्वारे नियमित पॅरामीटर्स पास करू शकता, परंतु this मूल्य लॉक केलेले आहे.
स्क्रिप्ट फाइलच्या जागतिक व्याप्तीमध्ये या स्निपेटचा विचार करा:
const arrow = () => console.log(this);
arrow();
कारण बाण जागतिक कोडमध्ये परिभाषित केला आहे, तो this जागतिक आहे this (विशेषत: window ब्राउझर स्क्रिप्टमध्ये), आणि ते कधीही बदलत नाही. कॉल करीत आहे arrow एका साध्या फंक्शन म्हणून, ते एखाद्या प्रॉपर्टीला असाइन केल्याने किंवा ते पास केल्याने या संदर्भात इनव्हॉइस केल्यावर नेहमीच समान ग्लोबल ऑब्जेक्ट लॉग होईल.
जेव्हा तुम्ही नियमित फंक्शन्स किंवा मेथड्समध्ये अॅरो फंक्शन्स नेस्ट करता तेव्हा खरोखरच मनोरंजक वर्तन दिसून येते. बाण बाह्य फंक्शन कॅप्चर करतो म्हणून this, ते कॉलबॅकसाठी एक शक्तिशाली साधन बनते ज्यांना नेहमीच्या .bind(this) समारंभ.
const counter = {
id: 42,
start() {
setTimeout(() => {
console.log(this.id); // uses counter.id
}, 1000);
},
};
If start आत एक पारंपारिक अनामिक फंक्शन वापरत होतो setTimeout, तुम्हाला मॅन्युअली बाइंड करावे लागेल this किंवा ते व्हेरिएबलमध्ये सेव्ह करा. बाणांसह, कॉलबॅक नैसर्गिकरित्या वारशाने मिळतो this आरोग्यापासून start, जे आहे counter, त्यामुळे this.id छपाई करतो 42 हेतूनुसार.
हे शब्दावली बंधन क्लासिक "का करते" हे देखील स्पष्ट करते this ऑब्जेक्ट लिटरल्समध्ये बाण वापरताना "बदल" प्रश्न. या दोन वस्तू पहा:
const obj1 = {
speak() {
console.log(this);
}
};
const obj2 = {
speak: () => {
console.log(this);
}
};
कॉल करीत आहे obj1.speak() छपाई करतो obj1, कारण speak ही एक नियमित पद्धत आहे आणि this कॉल साइटवर आधारित सेट केले आहे. या विरुद्ध, obj2.speak() बाहेरील लाकूडतोड this (अनेकदा window ब्राउझरमध्ये), कारण बाण ऑब्जेक्टला त्याच्या म्हणून वापरत नाही this. ऑब्जेक्ट लिटरल स्वतः नवीन तयार करत नाही this स्कोप; फक्त फंक्शन बॉडी ते करते आणि अॅरो फंक्शन्स ती पायरी वगळतात.
आता एक ऑब्जेक्ट पद्धत विचारात घ्या जी आतील बाण तयार करते आणि लगेच कॉल करते:
const obj3 = {
speak() {
(() => {
console.log(this);
})();
}
};
obj3.speak();
या परिस्थितीत, आतील बाण फंक्शन वारशाने मिळते this आरोग्यापासून speak, जे आहे obj3 जेव्हा म्हणतात obj3.speak(). जरी बाण हा एक नेस्टेड, ताबडतोब आवाहन केलेला फंक्शन असला तरी, तो अजूनही निर्देश करतो obj3, जागतिक वस्तू नाही. तेच शब्दकोशाचे सार आहे this: ते बाणाच्या कॉल साइटचे नाही तर आजूबाजूच्या व्याप्तीचे अनुसरण करते.
this फंक्शन्स, ऑब्जेक्ट्स आणि कन्स्ट्रक्टर्समध्ये
बाणांच्या कार्यांमध्ये खरोखर प्रभुत्व मिळविण्यासाठी आणि this, कसे ते पाहण्यास मदत होते this प्रत्येक प्रमुख संदर्भात कार्य करते: नियमित कार्ये, पद्धती, कन्स्ट्रक्टर, वर्ग आणि जागतिक व्याप्ती. एकदा ते नियम स्पष्ट झाले की, बाणाच्या वर्तनाबद्दल तर्क करणे खूप सोपे होते.
एका साध्या फंक्शनमध्ये (बाण नसलेले), this फंक्शन कसे बोलावले जाते यावर १००% अवलंबून असते. जर तुम्ही फोन केला तर fn() कडक मोडमध्ये, this is undefined; स्लोपी मोडमध्ये, प्रतिस्थापन बनवते this बनू globalThis. जर तुम्ही फोन केला तर obj.fn(), नंतर this is obj. हलवा fn वेगळ्या वस्तू किंवा चलाचे आणि मूल्याचे this त्यानुसार हालचाल करेल.
ऑब्जेक्ट लिटरलवर परिभाषित केलेल्या पद्धतीमध्ये, this ही पद्धत ज्या ऑब्जेक्टवर अॅक्सेस केली जाते ती ऑब्जेक्ट आहे, ती ऑब्जेक्ट नाही जिथे पद्धत मूळतः परिभाषित केली गेली होती. If obj.__proto__ एक पद्धत धरते आणि तुम्ही कॉल करता obj.method(), नंतर आत method, this is obj, प्रोटोटाइप नाही.
कन्स्ट्रक्टर हे आणखी एक विशेष प्रकरण आहे: जेव्हा तुम्ही फंक्शन कॉल करता तेव्हा new, this नव्याने तयार केलेल्या ऑब्जेक्ट इंस्टन्सशी बांधील आहे. उदाहरणार्थ, मध्ये function User(name) { this.name = name; }, कॉलिंग new User('Alex') संच this नवीन करण्यासाठी User ऑब्जेक्ट. जर कन्स्ट्रक्टर स्पष्टपणे नॉन-आदिम ऑब्जेक्ट परत करतो, तर तो परत केलेला ऑब्जेक्ट this चे अंतिम मूल्य म्हणून new अभिव्यक्ती
वर्ग वाक्यरचना या नियमांवर दोन मुख्य संदर्भांसह तयार होते: उदाहरण आणि स्थिर. कन्स्ट्रक्टर किंवा इन्स्टन्स मेथडमध्ये, this तुम्ही ज्या क्लास इंस्टन्सवर काम करत आहात त्याकडे निर्देश करते. स्टॅटिक मेथड्स किंवा स्टॅटिक इनिशिएलायझेशन ब्लॉक्समध्ये, this वर्गाचाच संदर्भ देते (किंवा वारसा द्वारे कॉल केल्यावर व्युत्पन्न वर्ग). इन्स्टन्स फील्डचे मूल्यांकन यासह केले जाते this नवीन उदाहरणाशी बांधील; स्थिर फील्ड पहा this क्लास कन्स्ट्रक्टर म्हणून.
व्युत्पन्न वर्ग कन्स्ट्रक्टर थोडे वेगळे वागतात: जोपर्यंत तुम्ही कॉल करत नाही तोपर्यंत super(), वापरण्यायोग्य नाही this. मागवत आहे super() सुरू करतो this बेस कन्स्ट्रक्टरला डेलिगेट करून; जर तुम्ही स्पष्टपणे वेगळा ऑब्जेक्ट परत केला तरच डेरिव्हेटिव्ह कन्स्ट्रक्टरमध्ये ते करण्यापूर्वी परत येण्याची परवानगी आहे.
जागतिक संदर्भात, this जावास्क्रिप्ट वातावरण तुमचा कोड कसा रॅप करते आणि कार्यान्वित करते यावर अवलंबून आहे. क्लासिक ब्राउझर स्क्रिप्टमध्ये, उच्च-स्तरीय this जागतिक ऑब्जेक्ट आहे; ES मॉड्यूलमध्ये, उच्च-स्तरीय this नेहमी आहे undefined. Node.js CommonJS मॉड्यूल्स अंतर्गत रॅप केलेले असतात आणि सहसा यासह कार्यान्वित केले जातात this वर सेट module.exports. HTML मधील इनलाइन इव्हेंट हँडलर गुणधर्म यासह कार्यान्वित करा this ज्या घटकाशी ते जोडलेले आहेत त्यावर सेट करा.
एक सूक्ष्म पण महत्त्वाचा तपशील: ऑब्जेक्ट लिटरल्स स्वतः नवीन परिचय देत नाहीत this व्याप्ती. लेखन const obj = { value: this }; एका स्क्रिप्टच्या आत बनवेल obj.value बाहेरील भाग समान करा this, ऑब्जेक्ट नाही. फक्त फंक्शन बॉडीज (आणि क्लास बॉडीज) एक समर्पित this बंधनकारक; बाण जाणूनबुजून ही पायरी वगळतात आणि इनहेरिट करतात.
कॉलबॅकसाठी अॅरो फंक्शन्स का उत्तम आहेत (आणि जेव्हा ते नसतात तेव्हा)
कारण बाणाचे फंक्शन जवळ येते this, ते अनेक कॉलबॅक परिस्थितींसाठी परिपूर्ण आहेत जिथे तुम्हाला कॉलबॅक आसपासच्या ऑब्जेक्ट किंवा संदर्भाचा संदर्भ देत राहावा असे वाटते. हे विशेषतः टाइमर, प्रॉमिस आणि अॅरे पद्धतींसह उपयुक्त आहे जसे की map, filterआणि reduce.
अशी एक पद्धत कल्पना करा जिथे काही गुणधर्म वारंवार अपडेट करावे लागतात, setInterval. पारंपारिक फंक्शन वापरून, this कॉलबॅकच्या आत ग्लोबल ऑब्जेक्टवर डीफॉल्ट असेल (किंवा असेल undefined कडक मोडमध्ये), म्हणून this.count तुमच्या उदाहरणाकडे निर्देश करणार नाही. बाण फंक्शनसह, कॉलबॅक नैसर्गिकरित्या वापरतो this बाह्य पद्धतीचा.
function Counter() {
this.count = 0;
setInterval(() => {
this.count++;
}, 1000);
}
बाणामुळे, this इंटरव्हल कॉलबॅकच्या आत म्हणजे Counter उदाहरणार्थ, नाही window. जर तो कॉलबॅक नियमित फंक्शन असता, तर तुम्हाला एकतर आवश्यक असते .bind(this) किंवा एक मध्यवर्ती चल जसे की const self = this; संदर्भ ठेवण्यासाठी.
अॅरो फंक्शन्स अॅरे पद्धती वापरून कोड सुलभ करतात, जिथे तुम्हाला अनेकदा काळजी नसते this अजिबात. जेव्हा तुम्ही पारंपारिक फंक्शन कॉलबॅक म्हणून पास करता, तेव्हा अंतर्निहित this सहसा आहे undefined, आणि तुम्ही ते विसरू शकता. बाणांमुळे हे स्पष्ट होते की हे फंक्शन फक्त इनपुट आणि आउटपुटचे शुद्ध मॅपिंग आहे.
const numbers = [1, 2, 3];
const doubled = numbers.map(n => n * 2);
तथापि, अशी काही महत्त्वाची प्रकरणे आहेत जिथे बाण फंक्शन्स चुकीची निवड असतात, विशेषतः जेव्हा तुम्हाला डायनॅमिकची आवश्यकता असते this. दोन क्लासिक अँटी-पॅटर्नमध्ये अॅरो फंक्शन्स ऑब्जेक्ट मेथड म्हणून आणि DOM इव्हेंट हँडलर म्हणून वापरल्या जातात जे यावर अवलंबून असतात this घटक असणे.
मांजरीच्या जीवनाचा मागोवा घेणारी एक वस्तू विचारात घ्या:
const cat = {
lives: 9,
jump: () => {
this.lives--; // bug: this is not cat
},
};
cat.jump();
पासून jump एक बाण आहे, this संदर्भ देत नाही cat पण काहीही असो this ऑब्जेक्ट लिटरल (बहुतेकदा ग्लोबल ऑब्जेक्ट) येथे तयार केले गेले होते. अभिप्रेत this.lives-- एकतर थ्रो करते (स्ट्रिकट मोडमध्ये) किंवा शांतपणे असंबंधित काहीतरी उत्परिवर्तन करते. येथे नियमित पद्धत वाक्यरचना वापरणे हा योग्य मार्ग आहे.
DOM इव्हेंट लिसनर्स सारखेच असतात: मानक पॅटर्न this.classList.toggle('on') इव्हेंट कॉलबॅक आत अवलंबून असते this कार्यक्रमाला चालना देणारा घटक होता. बाण फंक्शनसह, this आता घटकाकडे निर्देश करत नाही, म्हणून कोड खंडित होतो.
const button = document.getElementById('press');
button.addEventListener('click', () => {
this.classList.toggle('on'); // this is not button
});
या परिस्थितीत हँडलर सामान्य कार्य करणारा असावा जेणेकरून this ब्राउझरद्वारे बटण घटकाशी बांधलेले असते. जर तुमच्या लॉजिकनुसार अपेक्षा असेल तर अॅरो फंक्शन्स ड्रॉप-इन रिप्लेसमेंट म्हणून काम करत नाहीत this गतिमान कार्यक्रम लक्ष्य असणे.
आणखी एक सूक्ष्म कमतरता म्हणजे बाण फंक्शन्स वाक्यरचनात्मकदृष्ट्या अनामिक असतात. त्यांचे सहसा स्वतःचे नाव नसते (त्यांना नियुक्त केलेल्या कोणत्याही व्हेरिएबलच्या पलीकडे), ज्यामुळे स्टॅक ट्रेस थोडे कमी वर्णनात्मक आणि रिकर्सन थोडे क्लिष्ट होऊ शकते. बहुतेक वास्तविक जगात कोडमध्ये ते एक व्यवस्थापित करण्यायोग्य ट्रेड-ऑफ आहे, परंतु ते लक्षात ठेवण्यासारखे आहे.
विशेष प्रकरणे: गेटर्स, सेटर्स, बाउंड पद्धती आणि विषम कोपरे
गेटर्स आणि सेटर्स समान "कॉल साइट" नियम पाळतात: this ही ती वस्तू आहे जिथे मालमत्तेचा वापर केला जातो, जिथे ती मूळतः परिभाषित केली गेली होती ती वस्तू नाही. जर एखादा गेटर प्रोटोटाइपमधून वारशाने मिळाला असेल आणि तुम्ही त्याला व्युत्पन्न केलेल्या ऑब्जेक्टवर कॉल केला असेल, this गेटरच्या आत व्युत्पन्न ऑब्जेक्टचा संदर्भ आहे.
बांधलेल्या पद्धती तयार केल्या Function.prototype.bind तुम्हाला बाण फंक्शन्ससारखे काहीसे वर्तन देते, परंतु सामान्य फंक्शन्सच्या पातळीवर. जेव्हा तुम्ही फोन करता f.bind(obj), तुम्ही एक नवीन फंक्शन तयार करता ज्याचे this कायमचे निश्चित केले आहे obj, ते कसेही वापरले तरी. जेव्हा तुम्हाला जतन करण्याची आवश्यकता असते तेव्हा हे वर्गांमध्ये उपयुक्त ठरू शकते this जरी पद्धत वेगळी असली तरी.
class Example {
constructor() {
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log(this); // always the instance
}
}
इन्स्टन्स फील्ड म्हणून वापरल्या जाणाऱ्या बाउंड मेथड्स आणि अॅरो फंक्शन्सचा तोटा असा आहे की प्रत्येक इन्स्टन्सला फंक्शनची स्वतःची प्रत मिळते, ज्यामुळे मेमरी वापर वाढू शकतो. जेव्हा तुम्ही फक्त काही वारंवार वेगळ्या पद्धती बांधता तेव्हा ही तडजोड सहसा स्वीकार्य असते, परंतु कामगिरी-क्रिटिकल कोडमध्ये हे लक्षात ठेवण्यासारखे आहे.
काही लेगसी कॉर्नर केसेस देखील आहेत जिथे this वेगळ्या पद्धतीने वागते, जसे की कालबाह्य झालेल्या with विधान आत एक with (obj) { ... } ब्लॉक करणे, अशा फंक्शनला कॉल करणे जे चे गुणधर्म आहे obj तुम्ही लिहिले आहे असे प्रभावीपणे वागते obj.method(), त्यामुळे this बांधील आहे obj. आधुनिक कोडने टाळावे with, परंतु हा अपवाद समजून घेतल्याने हे स्पष्ट होते की this तरीही ते मूलभूतपणे फंक्शन कॉल कसा तयार होतो यावर अवलंबून असते.
HTML मधील इनलाइन इव्हेंट हँडलर्सना देखील एक विशेष नियम आहे: आजूबाजूचा इनलाइन हँडलर कोड पाहतो this घटक म्हणून, परंतु त्या हँडलरमध्ये परिभाषित केलेले अंतर्गत कार्ये नियमितकडे परत येतात this नियम म्हणून एक अंतर्गत पारंपारिक कार्य, जे कोणत्याही गोष्टीशी बांधील नाही, सहसा पाहेल this as globalThis (किंवा undefined (स्ट्रिक्ट मोडमध्ये), घटक नाही.
शेवटी, लक्षात ठेवा की बाण फंक्शन्समध्ये a नसते prototype प्रॉपर्टी आणि कन्स्ट्रक्टर म्हणून वापरली जाऊ शकत नाही new. प्रयत्नशील new MyArrow() TypeError टाकेल. जर तुम्हाला कन्स्ट्रक्टर म्हणून काम करू शकणारे फंक्शन हवे असेल, तर तुम्हाला रेग्युलर फंक्शन किंवा क्लास वापरावा लागेल.
हे तपशील लक्षात ठेवल्याने बाण फंक्शन्स आणि पारंपारिक फंक्शन्समध्ये निवड करणे खूप सोपे होते. जिथे तुम्हाला शब्दलेखन हवे असेल तिथे बाण वापरा. this आणि संक्षिप्त वाक्यरचना, आणि जेव्हा तुम्हाला गतिमान, कॉल-साइट-चालित आवश्यक असेल तेव्हा नियमित फंक्शन्सवर परत या this वर्तन किंवा कन्स्ट्रक्टर सिमेंटिक्स.
एकदा तुम्ही कसे ते आत्मसात केले की this प्रत्येक परिस्थितीत बांधील असताना, बाण फंक्शन्स बग्सचा आश्चर्यकारक स्रोत बनण्याऐवजी एक शक्तिशाली सहयोगी बनतात. ते कॉलबॅक आणि साधे रूपांतरणे यासारख्या सामान्य नमुन्यांना सुव्यवस्थित करतात, तर नियमित कार्ये त्यांच्या स्वतःवर अवलंबून असलेल्या भूमिका हाताळत राहतात. this बाइंडिंग, जसे की मेथड्स, कन्स्ट्रक्टर्स आणि डायनॅमिक इव्हेंट हँडलर.