javascript questions जावास्क्रिप्ट में कार्यों को अधिभार कैसे करें?




javascript programs (11)

इसके लिए आपको एक फ़ंक्शन बनाने की आवश्यकता है जो फ़ंक्शन को ऑब्जेक्ट में जोड़ती है, फिर यह फ़ंक्शन पर भेजे गए तर्कों की मात्रा के आधार पर निष्पादित होगी:

<script > 
//Main function to add the methods
function addMethod(object, name, fn) {
  var old = object[name];
  object[name] = function(){
    if (fn.length == arguments.length)
      return fn.apply(this, arguments)
    else if (typeof old == 'function')
      return old.apply(this, arguments);
  };
}


  var ninjas = {
   values: ["Dean Edwards", "Sam Stephenson", "Alex Russell"]
};

//Here we declare the first function with no arguments passed
  addMethod(ninjas, "find", function(){
    return this.values;
});

//Second function with one argument
  addMethod(ninjas, "find", function(name){
    var ret = [];
    for (var i = 0; i < this.values.length; i++)
      if (this.values[i].indexOf(name) == 0)
        ret.push(this.values[i]);
    return ret;
  });

//Third function with two arguments
  addMethod(ninjas, "find", function(first, last){
    var ret = [];
    for (var i = 0; i < this.values.length; i++)
      if (this.values[i] == (first + " " + last))
        ret.push(this.values[i]);
    return ret;
  });


//Now you can do:
ninjas.find();
ninjas.find("Sam");
ninjas.find("Dean", "Edwards")
</script>

ओवरलोडिंग के लिए शास्त्रीय (गैर-जेएस) दृष्टिकोण:

function myFunc(){
 //code
}

function myFunc(overloaded){
 //other code
}

जावास्क्रिप्ट एक ही नाम से एक से अधिक फ़ंक्शन परिभाषित नहीं होने देगा। इस तरह, इस तरह की चीजें दिखाती हैं:

function myFunc(options){
 if(options["overloaded"]){
  //code
 }
}

किसी ऑब्जेक्ट को ओवरलोड के साथ पास करने के अलावा जावास्क्रिप्ट में फंक्शन ओवरलोडिंग के लिए बेहतर कामकाज है?

ओवरलोड में गुजरने से फ़ंक्शन को वर्बोज़ बनने का कारण बन सकता है क्योंकि प्रत्येक संभावित अधिभार को सशर्त कथन की आवश्यकता होती है। //code सशर्त बयानों //code अंदर //code को पूरा करने के लिए फ़ंक्शंस का उपयोग करने से स्कॉप्स के साथ मुश्किल परिस्थितियां हो सकती हैं।


जो आप प्राप्त करने का प्रयास कर रहे हैं वह फ़ंक्शन के स्थानीय तर्क चर का उपयोग करके किया जाता है।

function foo() {
    if (arguments.length === 0) {
        //do something
    }
    if (arguments.length === 1) {
        //do something else
    }
}

foo(); //do something
foo('one'); //do something else

आप here कैसे काम करते here इसका एक बेहतर स्पष्टीकरण पा सकते हैं।


जेएस में ओवरलोडिंग के साथ कोई समस्या नहीं, पीबी कैसे ओवरलोडिंग समारोह को साफ कोड बनाए रखने के लिए?

आप दो चीजों के आधार पर स्वच्छ कोड रखने के लिए आगे का उपयोग कर सकते हैं:

  1. तर्कों की संख्या (फ़ंक्शन को कॉल करते समय)।
  2. तर्कों का प्रकार (जब फ़ंक्शन कॉल करें)

      function myFunc(){
          return window['myFunc_'+arguments.length+Array.from(arguments).map((arg)=>typeof arg).join('_')](...arguments);
       }
    
        /** one argument & this argument is string */
      function myFunc_1_string(){
    
      }
       //------------
       /** one argument & this argument is object */
      function myFunc_1_object(){
    
      }
      //----------
      /** two arguments & those arguments are both string */
      function myFunc_2_string_string(){
    
      }
       //--------
      /** Three arguments & those arguments are : id(number),name(string), callback(function) */
      function myFunc_3_number_string_function(){
                let args=arguments;
                  new Person(args[0],args[1]).onReady(args[3]);
      }
    
       //--- And so on ....   
    

मैं समान कार्यक्षमता के लिए तर्क समूहों के बीच अंतर करने की क्षमता प्राप्त करने के लिए एक मूल कार्य के भीतर उप कार्यों को जोड़ना चाहता हूं।

var doSomething = function() {
    var foo;
    var bar;
};

doSomething.withArgSet1 = function(arg0, arg1) {
    var obj = new doSomething();
    // do something the first way
    return obj;
};

doSomething.withArgSet2 = function(arg2, arg3) {
    var obj = new doSomething();
    // do something the second way
    return obj;
};

आप सख्ती से विधि अधिभार नहीं कर सकते हैं। java या c# में जिस तरह से समर्थित है उसे पसंद नहीं है।

मुद्दा यह है कि जावास्क्रिप्ट विधिवत ओवरलोडिंग का समर्थन नहीं करता है। इसलिए, यदि यह एक ही नाम के साथ दो या दो से अधिक कार्यों को देखता / पार्स करता है तो यह केवल अंतिम परिभाषित फ़ंक्शन पर विचार करेगा और पिछले लोगों को ओवरराइट करेगा।

जिस तरह से मुझे लगता है कि ज्यादातर मामलों के लिए उपयुक्त है, निम्नानुसार है -

मान लें कि आपके पास विधि है

function foo(x)
{
} 

जावास्क्रिप्ट में संभव नहीं है जो ओवरलोडिंग विधि के बजाय आप एक नई विधि को परिभाषित कर सकते हैं

fooNew(x,y,z)
{
}

और फिर निम्न कार्य को निम्नानुसार संशोधित करें -

function foo(x)
{
  if(arguments.length==2)
  {
     return fooNew(arguments[0],  arguments[1]);
  }
} 

यदि आपके पास ऐसी कई ओवरलोडेड विधि हैं, तो बस if-else कथन के मुकाबले switch का उपयोग switch पर विचार करें।

( अधिक जानकारी )


मैं तर्क संख्या के आधार पर थोड़ा अलग ओवरलोडिंग दृष्टिकोण का उपयोग कर रहा हूं। हालांकि मुझे विश्वास है कि जॉन फावसेट का दृष्टिकोण भी अच्छा है। यहां उदाहरण, जॉन रेजिग (jQuery के लेखक) स्पष्टीकरण के आधार पर कोड।

// o = existing object, n = function name, f = function.
    function overload(o, n, f){
        var old = o[n];
        o[n] = function(){
            if(f.length == arguments.length){
                return f.apply(this, arguments);
            }
            else if(typeof o == 'function'){
                return old.apply(this, arguments);
            }
        };
    }

प्रयोज्य:

var obj = {};
overload(obj, 'function_name', function(){ /* what we will do if no args passed? */});
overload(obj, 'function_name', function(first){ /* what we will do if 1 arg passed? */});
overload(obj, 'function_name', function(first, second){ /* what we will do if 2 args passed? */});
overload(obj, 'function_name', function(first,second,third){ /* what we will do if 3 args passed? */});
//... etc :)

जावास्क्रिप्ट में एक फ़ंक्शन ओवरलोड करना कई तरीकों से किया जा सकता है। उनमें से सभी में एक मास्टर फ़ंक्शन शामिल होता है जो या तो सभी प्रक्रियाओं, या प्रतिनिधियों को उप-कार्य / प्रक्रियाओं में करता है।

सबसे आम सरल तकनीकों में से एक में एक साधारण स्विच शामिल है:

function foo(a, b) {
    switch (arguments.length) {
    case 0:
        //do basic code
        break;
    case 1:
        //do code with `a`
        break;
    case 2:
    default:
        //do code with `a` & `b`
        break;
    }
}

एक और अधिक सुरुचिपूर्ण तकनीक एक सरणी का उपयोग करना होगा (या ऑब्जेक्ट यदि आप प्रत्येक तर्क गणना के लिए ओवरलोड नहीं कर रहे हैं):

fooArr = [
    function () {
    },
    function (a) {
    },
    function (a,b) {
    }
];
function foo(a, b) {
    return fooArr[arguments.length](a, b);
}

वह पिछला उदाहरण बहुत ही सुरुचिपूर्ण नहीं है, कोई भी fooArr को संशोधित कर सकता है, और यदि कोई foo को 2 से अधिक तर्कों में गुजरता है तो यह विफल हो जाएगा, इसलिए मॉड्यूल पैटर्न और कुछ चेक का उपयोग करने के लिए एक बेहतर रूप होगा:

var foo = (function () {
    var fns;
    fns = [
        function () {
        },
        function (a) {
        },
        function (a, b) {
        }
    ];
    function foo(a, b) {
        var fnIndex;
        fnIndex = arguments.length;
        if (fnIndex > foo.length) {
            fnIndex = foo.length;
        }
        return fns[fnIndex].call(this, a, b);
    }
    return foo;
}());

बेशक आपके fns गतिशील संख्याओं का उपयोग करना चाहते हैं, ताकि आप fns संग्रह के लिए किसी ऑब्जेक्ट का उपयोग कर सकें।

var foo = (function () {
    var fns;
    fns = {};
    fns[0] = function () {
    };
    fns[1] = function (a) {
    };
    fns[2] = function (a, b) {
    };
    fns.params = function (a, b /*, params */) {
    };
    function foo(a, b) {
        var fnIndex;
        fnIndex = arguments.length;
        if (fnIndex > foo.length) {
            fnIndex = 'params';
        }
        return fns[fnIndex].apply(this, Array.prototype.slice.call(arguments));
    }
    return foo;
}());

मेरी निजी वरीयता switch होने लगती है, हालांकि यह मास्टर फ़ंक्शन को बड़ा करता है। इस तकनीक का उपयोग करने का एक आम उदाहरण एक एक्सेसर / म्यूटेटर विधि होगा:

function Foo() {} //constructor
Foo.prototype = {
    bar: function (val) {
        switch (arguments.length) {
        case 0:
            return this._bar;
        case 1:
            this._bar = val;
            return this;
        }
    }
}

इसकी जांच करें:

http://www.codeproject.com/Articles/688869/Overloading-JavaScript-Functions

असल में आपकी कक्षा में, आप अपने कार्यों को संख्याबद्ध करते हैं जिन्हें आप अधिभारित करना चाहते हैं और फिर एक फ़ंक्शन कॉल के साथ आप फ़ंक्शन ओवरलोडिंग, तेज़ और आसान जोड़ते हैं।


चूंकि जावास्क्रिप्ट में फ़ंक्शन ओवरलोड विकल्प ऑब्जेक्ट नहीं है, इसके बजाए इसका उपयोग किया जा सकता है। यदि एक या दो आवश्यक तर्क हैं, तो उन्हें विकल्प ऑब्जेक्ट से अलग रखना बेहतर है। विकल्प ऑब्जेक्ट में मान पास नहीं होने पर विकल्प ऑब्जेक्ट और पॉप्युलेट मानों को डिफ़ॉल्ट मान पर कैसे उपयोग करें, इस पर एक उदाहरण दिया गया है।

function optionsObjectTest(x, y, opts) {
    opts = opts || {}; // default to an empty options object

    var stringValue = opts.stringValue || "string default value";
    var boolValue = !!opts.boolValue; // coerces value to boolean with a double negation pattern
    var numericValue = opts.numericValue === undefined ? 123 : opts.numericValue;

    return "{x:" + x + ", y:" + y + ", stringValue:'" + stringValue + "', boolValue:" + boolValue + ", numericValue:" + numericValue + "}";

}

विकल्प ऑब्जेक्ट का उपयोग करने के तरीके पर एक उदाहरण दिया गया है


जावास्क्रिप्ट में आप केवल एक बार फ़ंक्शन को कार्यान्वित कर सकते हैं और पैरामीटर myFunc() बिना फ़ंक्शन का आह्वान कर सकते हैं, फिर आप यह देखने के लिए जांचें कि विकल्प 'अपरिभाषित' हैं या नहीं।

function myFunc(options){
 if(typeof options != 'undefined'){
  //code
 }
}

https://github.com/jrf0110/leFunc

var getItems = leFunc({
  "string": function(id){
    // Do something
  },
  "string,object": function(id, options){
    // Do something else
  },
  "string,object,function": function(id, options, callback){
    // Do something different
    callback();
  },
  "object,string,function": function(options, message, callback){
    // Do something ca-raaaaazzzy
    callback();
  }
});

getItems("123abc"); // Calls the first function - "string"
getItems("123abc", {poop: true}); // Calls the second function - "string,object"
getItems("123abc", {butt: true}, function(){}); // Calls the third function - "string,object,function"
getItems({butt: true}, "What what?" function(){}); // Calls the fourth function - "object,string,function"




javascript