जावास्क्रिप्ट में ओवरलोडिंग पर बहस करने के लिए कई पहलू हैं:
परिवर्तनीय तर्क - आप विभिन्न प्रकार के तर्कों को पारित कर सकते हैं (प्रकार और मात्रा दोनों में) और फ़ंक्शन इस तरीके से व्यवहार करेगा जो उससे पारित तर्कों से मेल खाता है।
डिफ़ॉल्ट तर्क - आप एक तर्क के लिए एक डिफ़ॉल्ट मान को परिभाषित कर सकते हैं यदि यह पारित नहीं हुआ है।
नामित तर्क - तर्क आदेश अप्रासंगिक हो जाता है और आप सिर्फ नाम लेते हैं जो आप फ़ंक्शन में पास करना चाहते हैं।
नीचे तर्क हैंडलिंग की इन श्रेणियों में से प्रत्येक पर एक खंड है।
परिवर्तनीय तर्क
क्योंकि जावास्क्रिप्ट में तर्कों पर किसी प्रकार की जाँच नहीं है या तर्कों की आवश्यकता नहीं है, तो आपके पास इसका एक ही कार्यान्वयन myFunc()हो सकता है कि तर्कों, प्रकारों या तर्कों की जाँच करके इस पर तर्क दिया जा सकता है।
jQuery हर समय ऐसा करता है। आप कुछ तर्कों को वैकल्पिक बना सकते हैं या आप अपने कार्य में इस बात के आधार पर शाखा लगा सकते हैं कि क्या तर्क दिए गए हैं।
इन प्रकार के अधिभार को लागू करने में, आपके पास कई अलग-अलग तकनीकें हैं जिनका आप उपयोग कर सकते हैं:
- आप किसी भी दिए गए तर्क की उपस्थिति के लिए जाँच करके देख सकते हैं कि घोषित तर्क नाम मान है या नहीं
undefined।
- आप के साथ कुल मात्रा या तर्क की जाँच कर सकते हैं
arguments.length।
- आप किसी भी दिए गए तर्क के प्रकार की जांच कर सकते हैं।
- तर्कों की चर संख्याओं के लिए, आप
argumentsकिसी भी दिए गए तर्क तक पहुँचने के लिए छद्म-सरणी का उपयोग कर सकते हैं arguments[i]।
यहाँ कुछ उदाहरण हैं:
आइए देखें jQuery की obj.data()विधि। यह उपयोग के चार विभिन्न रूपों का समर्थन करता है:
obj.data("key");
obj.data("key", value);
obj.data();
obj.data(object);
प्रत्येक एक अलग व्यवहार को ट्रिगर करता है और, ओवरलोडिंग के इस गतिशील रूप का उपयोग किए बिना, चार अलग-अलग कार्यों की आवश्यकता होगी।
यहां बताया गया है कि अंग्रेजी में इन सभी विकल्पों में से कोई एक कैसे समझ सकता है और फिर मैं उन सभी को कोड में संयोजित करूंगा:
// get the data element associated with a particular key value
obj.data("key");
यदि पहला तर्क पास हो गया .data()है और दूसरा तर्क है undefined, तो कॉलर को इस फॉर्म का उपयोग करना होगा।
// set the value associated with a particular key
obj.data("key", value);
यदि दूसरा तर्क अपरिभाषित नहीं है, तो किसी विशेष कुंजी का मान सेट करें।
// get all keys/values
obj.data();
यदि कोई तर्क पारित नहीं होता है, तो लौटे हुए ऑब्जेक्ट में सभी कुंजी / मान लौटाएं।
// set all keys/values from the passed in object
obj.data(object);
यदि पहले तर्क का प्रकार एक सादा वस्तु है, तो उस ऑब्जेक्ट से सभी कुंजी / मान सेट करें।
यहां बताया गया है कि आप उन सभी को जावास्क्रिप्ट लॉजिक के एक सेट में कैसे जोड़ सकते हैं:
// method declaration for .data()
data: function(key, value) {
if (arguments.length === 0) {
// .data()
// no args passed, return all keys/values in an object
} else if (typeof key === "string") {
// first arg is a string, look at type of second arg
if (typeof value !== "undefined") {
// .data("key", value)
// set the value for a particular key
} else {
// .data("key")
// retrieve a value for a key
}
} else if (typeof key === "object") {
// .data(object)
// set all key/value pairs from this object
} else {
// unsupported arguments passed
}
},
इस तकनीक की कुंजी यह सुनिश्चित करना है कि आपके द्वारा स्वीकार किए जाने वाले सभी प्रकार के तर्क विशिष्ट रूप से पहचाने जाने योग्य हैं और इस बात को लेकर कोई भ्रम नहीं है कि कॉलर किस फॉर्म का उपयोग कर रहा है। इसके लिए आमतौर पर तर्कों को उचित रूप से क्रमबद्ध करने की आवश्यकता होती है और यह सुनिश्चित करना होता है कि तर्कों के प्रकार और स्थिति में पर्याप्त विशिष्टता है कि आप हमेशा बता सकें कि किस फॉर्म का उपयोग किया जा रहा है।
उदाहरण के लिए, यदि आपके पास एक फ़ंक्शन है जो तीन स्ट्रिंग तर्क लेता है:
obj.query("firstArg", "secondArg", "thirdArg");
आप तीसरे तर्क को आसानी से वैकल्पिक बना सकते हैं और आप आसानी से उस स्थिति का पता लगा सकते हैं, लेकिन आप केवल दूसरे तर्क को वैकल्पिक नहीं बना सकते हैं क्योंकि आप यह नहीं बता सकते हैं कि इनमें से किस कॉलर के पास होने का अर्थ है क्योंकि दूसरे की पहचान करने का कोई तरीका नहीं है तर्क का अर्थ दूसरा तर्क है या दूसरे तर्क को छोड़ दिया गया था, इसलिए दूसरे तर्क के स्थान पर वास्तव में तीसरा तर्क क्या है:
obj.query("firstArg", "secondArg");
obj.query("firstArg", "thirdArg");
चूंकि सभी तीन तर्क एक ही प्रकार के हैं, इसलिए आप विभिन्न तर्कों के बीच अंतर नहीं बता सकते हैं ताकि आपको पता न चले कि कॉलर का क्या इरादा है। इस कॉलिंग शैली के साथ, केवल तीसरा तर्क वैकल्पिक हो सकता है। यदि आप दूसरे तर्क को छोड़ना चाहते हैं, तो इसे null(या कुछ अन्य पता लगाने योग्य मूल्य) के बजाय पास करना होगा और आपका कोड पता लगाएगा:
obj.query("firstArg", null, "thirdArg");
यहाँ वैकल्पिक तर्क का एक jQuery उदाहरण है। दोनों तर्क वैकल्पिक हैं और पारित नहीं होने पर डिफ़ॉल्ट मान लेते हैं:
clone: function( dataAndEvents, deepDataAndEvents ) {
dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
return this.map( function () {
return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
});
},
यहां एक jQuery का उदाहरण दिया गया है जहां तर्क गायब हो सकता है या तीन अलग-अलग प्रकारों में से कोई एक हो सकता है जो आपको चार अलग-अलग अधिभार देता है:
html: function( value ) {
if ( value === undefined ) {
return this[0] && this[0].nodeType === 1 ?
this[0].innerHTML.replace(rinlinejQuery, "") :
null;
// See if we can take a shortcut and just use innerHTML
} else if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
(jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
!wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
value = value.replace(rxhtmlTag, "<$1></$2>");
try {
for ( var i = 0, l = this.length; i < l; i++ ) {
// Remove element nodes and prevent memory leaks
if ( this[i].nodeType === 1 ) {
jQuery.cleanData( this[i].getElementsByTagName("*") );
this[i].innerHTML = value;
}
}
// If using innerHTML throws an exception, use the fallback method
} catch(e) {
this.empty().append( value );
}
} else if ( jQuery.isFunction( value ) ) {
this.each(function(i){
var self = jQuery( this );
self.html( value.call(this, i, self.html()) );
});
} else {
this.empty().append( value );
}
return this;
},
नामित तर्क
अन्य भाषाएं (जैसे पायथन) एक को नामित तर्कों को केवल कुछ तर्कों को पारित करने और उन तर्कों से स्वतंत्र करने की अनुमति देती हैं जो वे पारित किए गए हैं। जावास्क्रिप्ट सीधे नामित तर्कों की विशेषता का समर्थन नहीं करता है। एक डिजाइन पैटर्न जो आमतौर पर इसके स्थान पर उपयोग किया जाता है, वह गुणों / मूल्यों का एक नक्शा पास करना है। यह गुणों और मूल्यों के साथ या ES6 और इसके बाद के संस्करण के साथ एक ऑब्जेक्ट को पास करके किया जा सकता है, आप वास्तव में एक मैप ऑब्जेक्ट को ही पास कर सकते हैं।
यहाँ एक सरल ES5 उदाहरण दिया गया है:
jQuery का $.ajax()एक प्रकार का उपयोग स्वीकार करता है जहां आप इसे एक एकल पैरामीटर पास करते हैं जो गुणों और मूल्यों के साथ एक नियमित जावास्क्रिप्ट ऑब्जेक्ट है। आप कौन से गुण पास करते हैं यह निर्धारित करते हैं कि कौन से तर्क / विकल्प अजाक्स कॉल में पारित किए जा रहे हैं। कुछ की आवश्यकता हो सकती है, कई वैकल्पिक हैं। चूंकि वे एक वस्तु पर गुण हैं, इसलिए कोई विशिष्ट आदेश नहीं है। वास्तव में, 30 से अधिक विभिन्न गुण हैं जो उस वस्तु पर पारित किए जा सकते हैं, केवल एक (url) की आवश्यकता है।
यहाँ एक उदाहरण है:
$.ajax({url: "http://www.example.com/somepath", data: myArgs, dataType: "json"}).then(function(result) {
// process result here
});
$.ajax()कार्यान्वयन के अंदर , यह केवल पूछताछ कर सकता है कि आने वाली वस्तु पर कौन से गुण पारित किए गए थे और नामित तर्क के रूप में उपयोग करते हैं। यह या तो के साथ for (prop in obj)या Object.keys(obj)उसके बाद एक सरणी में सभी गुणों को प्राप्त करके किया जा सकता है ।
इस तकनीक का उपयोग जावास्क्रिप्ट में बहुत अधिक किया जाता है जब बड़ी संख्या में तर्क होते हैं और / या कई तर्क वैकल्पिक होते हैं। नोट: यह कार्यान्वयन फ़ंक्शन पर एक सुनिश्चित करता है कि यह सुनिश्चित करने के लिए कि तर्कों का एक न्यूनतम मान्य सेट मौजूद है और कॉलर को कुछ डिबग फीडबैक देने के लिए कि अपर्याप्त तर्क पारित होने पर क्या गायब है (शायद एक सहायक संदेश संदेश के साथ एक अपवाद फेंककर) ।
ES6 वातावरण में, उपरोक्त पारित ऑब्जेक्ट के लिए डिफ़ॉल्ट गुण / मान बनाने के लिए विनाशकारी का उपयोग करना संभव है। इस संदर्भ लेख में इस पर अधिक विस्तार से चर्चा की गई है ।
यहाँ उस लेख से एक उदाहरण है:
function selectEntries({ start=0, end=-1, step=1 } = {}) {
···
};
यह डिफ़ॉल्ट गुण और मान के लिए मान बनाता है start, endऔर फ़ंक्शन पर stepपारित ऑब्जेक्ट पर गुण selectEntries()।
फ़ंक्शन तर्क के लिए डिफ़ॉल्ट मान
ES6 में, जावास्क्रिप्ट तर्कों के लिए डिफ़ॉल्ट मानों के लिए अंतर्निहित भाषा समर्थन जोड़ता है।
उदाहरण के लिए:
function multiply(a, b = 1) {
return a*b;
}
multiply(5); // 5
एमडीएन पर यहां इस्तेमाल किए जा सकने वाले तरीकों का और वर्णन ।