जावास्क्रिप्ट में C # एक्सटेंशन विधियों के लिए सटीक एनालॉग नहीं है। जावास्क्रिप्ट और सी # काफी अलग भाषाएं हैं।
निकटतम समान वस्तु सभी स्ट्रिंग ऑब्जेक्ट के प्रोटोटाइप ऑब्जेक्ट को संशोधित करना है String.prototype
:। सामान्य तौर पर, सबसे अच्छा अभ्यास पुस्तकालय कोड में निर्मित वस्तुओं के प्रोटोटाइप को संशोधित करने के लिए नहीं है, जिसका अर्थ है अन्य कोड जिन्हें आप नियंत्रित नहीं करते हैं, के साथ जोड़ा जाना है। (आवेदन में ऐसा करना जहां आप नियंत्रित करते हैं कि आवेदन में अन्य कोड क्या शामिल है, ठीक है।)
यदि आप करते हैं एक अंतर्निहित है, यह सबसे अच्छा है (अब तक) है कि एक बनाने के लिए के प्रोटोटाइप को संशोधित गैर गणनीय का उपयोग करके संपत्ति Object.defineProperty
(पहले किसी भी आधुनिक जावास्क्रिप्ट पर्यावरण, ES5 + तो बुनियादी तौर पर, और नहीं IE8¹ या)। अन्य स्ट्रिंग विधियों की गणना, लेखन क्षमता और विन्यास की तुलना करने के लिए, यह इस तरह दिखेगा:
Object.defineProperty(String.prototype, "SayHi", {
value: function SayHi() {
return "Hi " + this + "!";
},
writable: true,
configurable: true
});
(के लिए डिफ़ॉल्ट enumerable
है false
)
यदि आपको अप्रचलित वातावरण का समर्थन करने की आवश्यकता है, तो String.prototype
, विशेष रूप से, आप संभवत: एक अलग संपत्ति बनाने के साथ दूर हो सकते हैं:
String.prototype.SayHi = function SayHi() {
return "Hi " + this + "!";
};
यह एक अच्छा विचार नहीं है, लेकिन आप इससे दूर हो सकते हैं। के साथ Array.prototype
या कभी नहीं Object.prototype
; उन पर अनगिनत गुण पैदा करना एक बुरी बात है। ™
विवरण:
जावास्क्रिप्ट एक प्रोटोटाइप भाषा है। इसका मतलब है कि हर वस्तु एक प्रोटोटाइप ऑब्जेक्ट द्वारा समर्थित है । जावास्क्रिप्ट में, उस प्रोटोटाइप को चार तरीकों में से एक में सौंपा गया है:
- ऑब्जेक्ट के लिए निर्माता फ़ंक्शन द्वारा (जैसे, अपने प्रोटोटाइप के
new Foo
साथ ऑब्जेक्ट बनाता है Foo.prototype
)
Object.create
ES5 (2009) में जोड़े गए फ़ंक्शन द्वारा
- द्वारा
__proto__
एक्सेसर गुण (ES2015 +, केवल वेब ब्राउज़र पर, कुछ वातावरणों से पहले यह मानकीकरण किया गया था में ही अस्तित्व में) या Object.setPrototypeOf
(ES2015 +)
- किसी आदिम के लिए ऑब्जेक्ट बनाते समय जावास्क्रिप्ट इंजन द्वारा क्योंकि आप इस पर एक विधि कह रहे हैं (इसे कभी-कभी "पदोन्नति" कहा जाता है)
इसलिए आपके उदाहरण में, चूंकि firstName
एक स्ट्रिंग आदिम है, यह एक String
उदाहरण के लिए प्रचारित हो जाता है जब भी आप इस पर एक विधि कहते हैं, और उस String
उदाहरण का प्रोटोटाइप है String.prototype
। तो एक संपत्ति को String.prototype
उस संदर्भ में जोड़ने से आपका SayHi
कार्य उस फ़ंक्शन को सभी String
उदाहरणों पर उपलब्ध होता है (और प्रभावी रूप से स्ट्रिंग प्राइमेटिव पर, क्योंकि वे पदोन्नत हो जाते हैं)।
उदाहरण:
Object.defineProperty(String.prototype, "SayHi", {
value: function SayHi() {
return "Hi " + this + "!";
},
writable: true,
configurable: true
});
console.log("Charlie".SayHi());
इस और C # विस्तार विधियों के बीच कुछ प्रमुख अंतर हैं:
(जैसा कि डगआर ने एक टिप्पणी में कहा है) सी # के विस्तार के तरीकों को null
संदर्भों पर बुलाया जा सकता है । यदि आपके पास string
एक्सटेंशन विधि है, तो यह कोड:
string s = null;
s.YourExtensionMethod();
काम करता है। यह जावास्क्रिप्ट के साथ सच नहीं है; null
इसका अपना प्रकार है, और null
त्रुटि पर कोई भी संपत्ति संदर्भ । (और यहां तक कि अगर यह नहीं था, तो नल प्रकार के लिए कोई प्रोटोटाइप नहीं है।)
(जैसा कि क्रिस ने एक टिप्पणी में बताया है) C # की एक्सटेंशन विधियाँ वैश्विक नहीं हैं। वे केवल तभी सुलभ होते हैं जब उनके द्वारा परिभाषित नाम स्थान एक्सटेंशन विधि का उपयोग करके कोड द्वारा उपयोग किया जाता है। (वे वास्तव में स्टैटिक कॉल के लिए सिंटैक्टिक शुगर हैं, यही वजह है कि वे काम करते हैं null
।) यह जावास्क्रिप्ट में सच नहीं है: यदि आप एक बिल्ट-इन के प्रोटोटाइप को बदलते हैं, तो यह परिवर्तन पूरे दायरे में सभी कोड द्वारा देखा जाता है। ऐसा करें कि (एक क्षेत्र वैश्विक वातावरण और उससे जुड़ी आंतरिक वस्तुएं हैं, आदि)। इसलिए यदि आप एक वेब पेज में ऐसा करते हैं, तो उस पेज पर आपके द्वारा लोड किए गए सभी कोड परिवर्तन को देखते हैं। यदि आप Node.js मॉड्यूल में ऐसा करते हैं, तो सभीकोड को उसी दायरे में लोड किया जाता है, क्योंकि मॉड्यूल में परिवर्तन दिखाई देगा। दोनों मामलों में, यही कारण है कि आप लाइब्रेरी कोड में ऐसा नहीं करते हैं। (वेब वर्कर्स और Node.js वर्कर थ्रेड्स अपने दायरे में लोड किए जाते हैं, इसलिए उनके पास एक अलग वैश्विक वातावरण और मुख्य थ्रेड की तुलना में अलग-अलग इंट्रिंसिक्स होते हैं। लेकिन वह दायरे अभी भी किसी भी मॉड्यूल के साथ साझा किया जाता है जिसे वे लोड करते हैं।)
Object.defineProperty
DOM IE8 में है , लेकिन यह केवल DOM ऑब्जेक्ट्स पर काम करता है, जावास्क्रिप्ट ऑब्जेक्ट्स पर नहीं। String.prototype
एक जावास्क्रिप्ट ऑब्जेक्ट है।