How to overload functions in javascript?











up vote
83
down vote

favorite
36












Classical (non-js) approach to overloading:



function myFunc(){
//code
}

function myFunc(overloaded){
//other code
}


Javascript wont let more than one function be defined with the same name. As such, things like this show up:



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


Is there a better workaround for function overloading in javascript other than passing an object with the overloads in it?



Passing in overloads can quickly cause a function to become too verbose because each possible overload would then need a conditional statement. Using functions to accomplish the //code inside of those conditional statements can cause tricky situations with scopes.










share|improve this question


















  • 1




    Then you are thinking about javascript wrong; if you have issues with overloads and scope, you should probably have a different method name as it sounds like it's doing another job
    – joshcomley
    Jun 1 '12 at 19:04










  • @joshcomley - Overloads and scope require code to handle. I am merely trying to make sure the code that I use is as efficient as possible. Handling scopes with workarounds is fine, but I prefer to at least try to use best practice methods.
    – Travis J
    Jun 1 '12 at 19:06






  • 2




    possible duplicate of Function overloading in Javascript - Best practices
    – cdeszaq
    Apr 28 '14 at 14:18















up vote
83
down vote

favorite
36












Classical (non-js) approach to overloading:



function myFunc(){
//code
}

function myFunc(overloaded){
//other code
}


Javascript wont let more than one function be defined with the same name. As such, things like this show up:



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


Is there a better workaround for function overloading in javascript other than passing an object with the overloads in it?



Passing in overloads can quickly cause a function to become too verbose because each possible overload would then need a conditional statement. Using functions to accomplish the //code inside of those conditional statements can cause tricky situations with scopes.










share|improve this question


















  • 1




    Then you are thinking about javascript wrong; if you have issues with overloads and scope, you should probably have a different method name as it sounds like it's doing another job
    – joshcomley
    Jun 1 '12 at 19:04










  • @joshcomley - Overloads and scope require code to handle. I am merely trying to make sure the code that I use is as efficient as possible. Handling scopes with workarounds is fine, but I prefer to at least try to use best practice methods.
    – Travis J
    Jun 1 '12 at 19:06






  • 2




    possible duplicate of Function overloading in Javascript - Best practices
    – cdeszaq
    Apr 28 '14 at 14:18













up vote
83
down vote

favorite
36









up vote
83
down vote

favorite
36






36





Classical (non-js) approach to overloading:



function myFunc(){
//code
}

function myFunc(overloaded){
//other code
}


Javascript wont let more than one function be defined with the same name. As such, things like this show up:



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


Is there a better workaround for function overloading in javascript other than passing an object with the overloads in it?



Passing in overloads can quickly cause a function to become too verbose because each possible overload would then need a conditional statement. Using functions to accomplish the //code inside of those conditional statements can cause tricky situations with scopes.










share|improve this question













Classical (non-js) approach to overloading:



function myFunc(){
//code
}

function myFunc(overloaded){
//other code
}


Javascript wont let more than one function be defined with the same name. As such, things like this show up:



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


Is there a better workaround for function overloading in javascript other than passing an object with the overloads in it?



Passing in overloads can quickly cause a function to become too verbose because each possible overload would then need a conditional statement. Using functions to accomplish the //code inside of those conditional statements can cause tricky situations with scopes.







javascript






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jun 1 '12 at 18:59









Travis J

63.2k28148219




63.2k28148219








  • 1




    Then you are thinking about javascript wrong; if you have issues with overloads and scope, you should probably have a different method name as it sounds like it's doing another job
    – joshcomley
    Jun 1 '12 at 19:04










  • @joshcomley - Overloads and scope require code to handle. I am merely trying to make sure the code that I use is as efficient as possible. Handling scopes with workarounds is fine, but I prefer to at least try to use best practice methods.
    – Travis J
    Jun 1 '12 at 19:06






  • 2




    possible duplicate of Function overloading in Javascript - Best practices
    – cdeszaq
    Apr 28 '14 at 14:18














  • 1




    Then you are thinking about javascript wrong; if you have issues with overloads and scope, you should probably have a different method name as it sounds like it's doing another job
    – joshcomley
    Jun 1 '12 at 19:04










  • @joshcomley - Overloads and scope require code to handle. I am merely trying to make sure the code that I use is as efficient as possible. Handling scopes with workarounds is fine, but I prefer to at least try to use best practice methods.
    – Travis J
    Jun 1 '12 at 19:06






  • 2




    possible duplicate of Function overloading in Javascript - Best practices
    – cdeszaq
    Apr 28 '14 at 14:18








1




1




Then you are thinking about javascript wrong; if you have issues with overloads and scope, you should probably have a different method name as it sounds like it's doing another job
– joshcomley
Jun 1 '12 at 19:04




Then you are thinking about javascript wrong; if you have issues with overloads and scope, you should probably have a different method name as it sounds like it's doing another job
– joshcomley
Jun 1 '12 at 19:04












@joshcomley - Overloads and scope require code to handle. I am merely trying to make sure the code that I use is as efficient as possible. Handling scopes with workarounds is fine, but I prefer to at least try to use best practice methods.
– Travis J
Jun 1 '12 at 19:06




@joshcomley - Overloads and scope require code to handle. I am merely trying to make sure the code that I use is as efficient as possible. Handling scopes with workarounds is fine, but I prefer to at least try to use best practice methods.
– Travis J
Jun 1 '12 at 19:06




2




2




possible duplicate of Function overloading in Javascript - Best practices
– cdeszaq
Apr 28 '14 at 14:18




possible duplicate of Function overloading in Javascript - Best practices
– cdeszaq
Apr 28 '14 at 14:18












13 Answers
13






active

oldest

votes

















up vote
100
down vote



accepted










There are multiple aspects to argument overloading in Javascript:




  1. Variable arguments - You can pass different sets of arguments (in both type and quantity) and the function will behave in a way that matches the arguments passed to it.


  2. Default arguments - You can define a default value for an argument if it is not passed.


  3. Named arguments - Argument order becomes irrelevant and you just name which arguments you want to pass to the function.



Below is a section on each of these categories of argument handling.



Variable Arguments



Because javascript has no type checking on arguments or required qty of arguments, you can just have one implementation of myFunc() that can adapt to what arguments were passed to it by checking the type, presence or quantity of arguments.



jQuery does this all the time. You can make some of the arguments optional or you can branch in your function depending upon what arguments are passed to it.



In implementing these types of overloads, you have several different techniques you can use:




  1. You can check for the presence of any given argument by checking to see if the declared argument name value is undefined.

  2. You can check the total quantity or arguments with arguments.length.

  3. You can check the type of any given argument.

  4. For variable numbers of arguments, you can use the arguments pseudo-array to access any given argument with arguments[i].


Here are some examples:



Let's look at jQuery's obj.data() method. It supports four different forms of usage:



obj.data("key");
obj.data("key", value);
obj.data();
obj.data(object);


Each one triggers a different behavior and, without using this dynamic form of overloading, would require four separate functions.



Here's how one can discern between all these options in English and then I'll combine them all in code:



// get the data element associated with a particular key value
obj.data("key");


If the first argument passed to .data() is a string and the second argument is undefined, then the caller must be using this form.





// set the value associated with a particular key
obj.data("key", value);


If the second argument is not undefined, then set the value of a particular key.





// get all keys/values
obj.data();


If no arguments are passed, then return all keys/values in a returned object.





// set all keys/values from the passed in object
obj.data(object);


If the type of the first argument is a plain object, then set all keys/values from that object.





Here's how you could combine all of those in one set of javascript logic:



 // 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
}
},




The key to this technique is to make sure that all forms of arguments you want to accept are uniquely identifiable and there is never any confusion about which form the caller is using. This generally requires ordering the arguments appropriately and making sure that there is enough uniqueness in the type and position of the arguments that you can always tell which form is being used.



For example, if you have a function that takes three string arguments:



obj.query("firstArg", "secondArg", "thirdArg");


You can easily make the third argument optional and you can easily detect that condition, but you cannot make only the second argument optional because you can't tell which of these the caller means to be passing because there is no way to identify if the second argument is meant to be the second argument or the second argument was omitted so what's in the second argument's spot is actually the third argument:



obj.query("firstArg", "secondArg");
obj.query("firstArg", "thirdArg");


Since all three arguments are the same type, you can't tell the difference between different arguments so you don't know what the caller intended. With this calling style, only the third argument can be optional. If you wanted to omit the second argument, it would have to be passed as null (or some other detectable value) instead and your code would detect that:



obj.query("firstArg", null, "thirdArg");




Here's a jQuery example of optional arguments. both arguments are optional and take on default values if not passed:



clone: function( dataAndEvents, deepDataAndEvents ) {
dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;

return this.map( function () {
return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
});
},


Here's a jQuery example where the argument can be missing or any one of three different types which gives you four different overloads:



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;
},




Named Arguments



Other languages (like Python) allow one to pass named arguments as a means of passing only some arguments and making the arguments independent of the order they are passed in. Javascript does not directly support the feature of named arguments. A design pattern that is commonly used in its place is to pass a map of properties/values. This can be done by passing an object with properties and values or in ES6 and above, you could actually pass a Map object itself.



Here's a simple ES5 example:



jQuery's $.ajax() accepts a form of usage where you just pass it a single parameter which is a regular Javascript object with properties and values. Which properties you pass it determine which arguments/options are being passed to the ajax call. Some may be required, many are optional. Since they are properties on an object, there is no specific order. In fact, there are more than 30 different properties that can be passed on that object, only one (the url) is required.



Here's an example:



$.ajax({url: "http://www.example.com/somepath", data: myArgs, dataType: "json"}).then(function(result) {
// process result here
});


Inside of the $.ajax() implementation, it can then just interrogate which properties were passed on the incoming object and use those as named arguments. This can be done either with for (prop in obj) or by getting all the properties into an array with Object.keys(obj) and then iterating that array.



This technique is used very commonly in Javascript when there are large numbers of arguments and/or many arguments are optional. Note: this puts an onus on the implementating function to make sure that a minimal valid set of arguments is present and to give the caller some debug feedback what is missing if insufficient arguments are passed (probably by throwing an exception with a helpful error message).



In an ES6 environment, it is possible to use destructuring to create default properties/values for the above passed object. This is discussed in more detail in this reference article.



Here's one example from that article:



function selectEntries({ start=0, end=-1, step=1 } = {}) {
···
};


This creates default properties and values for the start, end and step properties on an object passed to the selectEntries() function.



Default values for function arguments



In ES6, Javascript adds built-in language support for default values for arguments.



For example:



function multiply(a, b = 1) {
return a*b;
}

multiply(5); // 5


Further description of the ways this can be used here on MDN.






share|improve this answer























  • So I should just stick with an adaptable function and accept that as best practice for implementing the function overload facade?
    – Travis J
    Jun 1 '12 at 19:11






  • 2




    @TravisJ - yes, adaptable function is the way overloads are done in Javascript. Your other option is to use a separately named function with different arguments. If the two implementations have nothing in common, then either is an acceptable practice. If the two implementations are essentially doing the same thing, but just starting with different arguments, then I think it makes your interface more compact to use the adaptable function and it gives you an opportunity to share code between the two related implementations.
    – jfriend00
    Jun 1 '12 at 19:14












  • Added some code examples, explained in both English and in actual code.
    – jfriend00
    Oct 26 '14 at 22:49










  • I am getting an error, unexpected token '=' on the latest version of Safari when I try this resetProgressBar: function(display_errors, lockout = false).
    – Nick
    Jul 19 '16 at 2:46












  • @Nick - Per this ES6 compatibility table, default parameter values should work in Safari 10 and later. Per this MDN page, it says "no support" in Safari. I don't have a Mac so I can't test it out myself. It seems to generally be one of the later implemented ES6 features across many browsers. For example, it doesn't look like it's in iOS9 yet.
    – jfriend00
    Jul 19 '16 at 4:15




















up vote
30
down vote













Overloading a function in JavaScript can be done in many ways. All of them involve a single master function that either performs all the processes, or delegates to sub-functions/processes.



One of the most common simple techniques involves a simple switch:



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;
}
}


A more elegant technique would be to use an array (or object if you're not making overloads for every argument count):



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


That previous example isn't very elegant, anyone could modify fooArr, and it would fail if someone passes in more than 2 arguments to foo, so a better form would be to use a module pattern and a few checks:



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;
}());


Of course your overloads might want to use a dynamic number of parameters, so you could use an object for the fns collection.



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;
}());




My personal preference tends to be the switch, although it does bulk up the master function. A common example of where I'd use this technique would be a accessor/mutator method:



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





share|improve this answer























  • This is a nice example of an alternative :)
    – Travis J
    Jun 1 '12 at 19:04






  • 1




    Nice, I like that 2nd technique
    – Nick Rolando
    Jun 1 '12 at 19:12




















up vote
5
down vote













You cannot do method overloading in strict sense. Not like the way it is supported in java or c#.



The issue is that JavaScript does NOT natively support method overloading. So, if it sees/parses two or more functions with a same names it’ll just consider the last defined function and overwrite the previous ones.



One of the way I think is suitable for most of the case is follows -



Lets say you have method



function foo(x)
{
}


Instead of overloading method which is not possible in javascript you can define a new method



fooNew(x,y,z)
{
}


and then modify the 1st function as follows -



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


If you have many such overloaded method consider using switch than just if-else statements.



(more details)






share|improve this answer






























    up vote
    4
    down vote













    I am using a bit different overloading approach based on arguments number.
    However i believe John Fawcett's approach is also good.
    Here the example, code based on John Resig's (jQuery's Author) explanations.



    // 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);
    }
    };
    }


    usability:



    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 :)





    share|improve this answer




























      up vote
      3
      down vote













      I tried to develop an elegant solution to this problem described here. And you can find the demo here. The usage looks like this:



      var out = def({
      'int': function(a) {
      alert('Here is int '+a);
      },

      'float': function(a) {
      alert('Here is float '+a);
      },

      'string': function(a) {
      alert('Here is string '+a);
      },

      'int,string': function(a, b) {
      alert('Here is an int '+a+' and a string '+b);
      },
      'default': function(obj) {
      alert('Here is some other value '+ obj);
      }

      });

      out('ten');
      out(1);
      out(2, 'robot');
      out(2.5);
      out(true);


      The methods used to achieve this:



      var def = function(functions, parent) {
      return function() {
      var types = ;
      var args = ;
      eachArg(arguments, function(i, elem) {
      args.push(elem);
      types.push(whatis(elem));
      });
      if(functions.hasOwnProperty(types.join())) {
      return functions[types.join()].apply(parent, args);
      } else {
      if (typeof functions === 'function')
      return functions.apply(parent, args);
      if (functions.hasOwnProperty('default'))
      return functions['default'].apply(parent, args);
      }
      };
      };

      var eachArg = function(args, fn) {
      var i = 0;
      while (args.hasOwnProperty(i)) {
      if(fn !== undefined)
      fn(i, args[i]);
      i++;
      }
      return i-1;
      };

      var whatis = function(val) {

      if(val === undefined)
      return 'undefined';
      if(val === null)
      return 'null';

      var type = typeof val;

      if(type === 'object') {
      if(val.hasOwnProperty('length') && val.hasOwnProperty('push'))
      return 'array';
      if(val.hasOwnProperty('getDate') && val.hasOwnProperty('toLocaleTimeString'))
      return 'date';
      if(val.hasOwnProperty('toExponential'))
      type = 'number';
      if(val.hasOwnProperty('substring') && val.hasOwnProperty('length'))
      return 'string';
      }

      if(type === 'number') {
      if(val.toString().indexOf('.') > 0)
      return 'float';
      else
      return 'int';
      }

      return type;
      };





      share|improve this answer



















      • 1




        A function to handle the inputs, very clever.
        – Travis J
        Apr 10 '13 at 1:23


















      up vote
      3
      down vote













      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"





      share|improve this answer






























        up vote
        3
        down vote













        In javascript you can implement the function just once and invoke the function without the parameters myFunc() You then check to see if options is 'undefined'



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





        share|improve this answer






























          up vote
          2
          down vote













          Check this out:



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



          Basically in your class, you number your functions that you want to be overloaded and then with one function call you add function overloading, fast and easy.






          share|improve this answer




























            up vote
            2
            down vote













            Since JavaScript doesn't have function overload options object can be used instead. If there are one or two required arguments, it's better to keep them separate from the options object. Here is an example on how to use options object and populated values to default value in case if value was not passed in options object.



            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 + "}";


            }



            here is an example on how to use options object






            share|improve this answer




























              up vote
              2
              down vote













              For this you need to create a function that adds the function to an object, then it will execute depending on the amount of arguments you send to the function:



              <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>





              share|improve this answer




























                up vote
                2
                down vote













                No Problem with Overloading in JS , The pb how to maintain a clean code when overloading function ?



                You can use a forward to have clean code , based on two things:




                1. Number of arguments (when calling the function).


                2. Type of arguments (when callin the function)



                    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 ....







                share|improve this answer




























                  up vote
                  0
                  down vote













                  I like to add sub functions within a parent function to achieve the ability to differentiate between argument groups for the same functionality.



                  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;
                  };





                  share|improve this answer




























                    up vote
                    0
                    down vote













                    What you are trying to achieve is best done using the function's local arguments variable.



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

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


                    You can find a better explanation of how this works here.






                    share|improve this answer





















                    • And what about collision detection? This is a nice way to use parameterless functions or to check for existence, but not really best practice when it comes to overloading.
                      – Travis J
                      Oct 8 '13 at 14:10












                    protected by Tushar Gupta Oct 4 '14 at 14:52



                    Thank you for your interest in this question.
                    Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                    Would you like to answer one of these unanswered questions instead?














                    13 Answers
                    13






                    active

                    oldest

                    votes








                    13 Answers
                    13






                    active

                    oldest

                    votes









                    active

                    oldest

                    votes






                    active

                    oldest

                    votes








                    up vote
                    100
                    down vote



                    accepted










                    There are multiple aspects to argument overloading in Javascript:




                    1. Variable arguments - You can pass different sets of arguments (in both type and quantity) and the function will behave in a way that matches the arguments passed to it.


                    2. Default arguments - You can define a default value for an argument if it is not passed.


                    3. Named arguments - Argument order becomes irrelevant and you just name which arguments you want to pass to the function.



                    Below is a section on each of these categories of argument handling.



                    Variable Arguments



                    Because javascript has no type checking on arguments or required qty of arguments, you can just have one implementation of myFunc() that can adapt to what arguments were passed to it by checking the type, presence or quantity of arguments.



                    jQuery does this all the time. You can make some of the arguments optional or you can branch in your function depending upon what arguments are passed to it.



                    In implementing these types of overloads, you have several different techniques you can use:




                    1. You can check for the presence of any given argument by checking to see if the declared argument name value is undefined.

                    2. You can check the total quantity or arguments with arguments.length.

                    3. You can check the type of any given argument.

                    4. For variable numbers of arguments, you can use the arguments pseudo-array to access any given argument with arguments[i].


                    Here are some examples:



                    Let's look at jQuery's obj.data() method. It supports four different forms of usage:



                    obj.data("key");
                    obj.data("key", value);
                    obj.data();
                    obj.data(object);


                    Each one triggers a different behavior and, without using this dynamic form of overloading, would require four separate functions.



                    Here's how one can discern between all these options in English and then I'll combine them all in code:



                    // get the data element associated with a particular key value
                    obj.data("key");


                    If the first argument passed to .data() is a string and the second argument is undefined, then the caller must be using this form.





                    // set the value associated with a particular key
                    obj.data("key", value);


                    If the second argument is not undefined, then set the value of a particular key.





                    // get all keys/values
                    obj.data();


                    If no arguments are passed, then return all keys/values in a returned object.





                    // set all keys/values from the passed in object
                    obj.data(object);


                    If the type of the first argument is a plain object, then set all keys/values from that object.





                    Here's how you could combine all of those in one set of javascript logic:



                     // 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
                    }
                    },




                    The key to this technique is to make sure that all forms of arguments you want to accept are uniquely identifiable and there is never any confusion about which form the caller is using. This generally requires ordering the arguments appropriately and making sure that there is enough uniqueness in the type and position of the arguments that you can always tell which form is being used.



                    For example, if you have a function that takes three string arguments:



                    obj.query("firstArg", "secondArg", "thirdArg");


                    You can easily make the third argument optional and you can easily detect that condition, but you cannot make only the second argument optional because you can't tell which of these the caller means to be passing because there is no way to identify if the second argument is meant to be the second argument or the second argument was omitted so what's in the second argument's spot is actually the third argument:



                    obj.query("firstArg", "secondArg");
                    obj.query("firstArg", "thirdArg");


                    Since all three arguments are the same type, you can't tell the difference between different arguments so you don't know what the caller intended. With this calling style, only the third argument can be optional. If you wanted to omit the second argument, it would have to be passed as null (or some other detectable value) instead and your code would detect that:



                    obj.query("firstArg", null, "thirdArg");




                    Here's a jQuery example of optional arguments. both arguments are optional and take on default values if not passed:



                    clone: function( dataAndEvents, deepDataAndEvents ) {
                    dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
                    deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;

                    return this.map( function () {
                    return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
                    });
                    },


                    Here's a jQuery example where the argument can be missing or any one of three different types which gives you four different overloads:



                    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;
                    },




                    Named Arguments



                    Other languages (like Python) allow one to pass named arguments as a means of passing only some arguments and making the arguments independent of the order they are passed in. Javascript does not directly support the feature of named arguments. A design pattern that is commonly used in its place is to pass a map of properties/values. This can be done by passing an object with properties and values or in ES6 and above, you could actually pass a Map object itself.



                    Here's a simple ES5 example:



                    jQuery's $.ajax() accepts a form of usage where you just pass it a single parameter which is a regular Javascript object with properties and values. Which properties you pass it determine which arguments/options are being passed to the ajax call. Some may be required, many are optional. Since they are properties on an object, there is no specific order. In fact, there are more than 30 different properties that can be passed on that object, only one (the url) is required.



                    Here's an example:



                    $.ajax({url: "http://www.example.com/somepath", data: myArgs, dataType: "json"}).then(function(result) {
                    // process result here
                    });


                    Inside of the $.ajax() implementation, it can then just interrogate which properties were passed on the incoming object and use those as named arguments. This can be done either with for (prop in obj) or by getting all the properties into an array with Object.keys(obj) and then iterating that array.



                    This technique is used very commonly in Javascript when there are large numbers of arguments and/or many arguments are optional. Note: this puts an onus on the implementating function to make sure that a minimal valid set of arguments is present and to give the caller some debug feedback what is missing if insufficient arguments are passed (probably by throwing an exception with a helpful error message).



                    In an ES6 environment, it is possible to use destructuring to create default properties/values for the above passed object. This is discussed in more detail in this reference article.



                    Here's one example from that article:



                    function selectEntries({ start=0, end=-1, step=1 } = {}) {
                    ···
                    };


                    This creates default properties and values for the start, end and step properties on an object passed to the selectEntries() function.



                    Default values for function arguments



                    In ES6, Javascript adds built-in language support for default values for arguments.



                    For example:



                    function multiply(a, b = 1) {
                    return a*b;
                    }

                    multiply(5); // 5


                    Further description of the ways this can be used here on MDN.






                    share|improve this answer























                    • So I should just stick with an adaptable function and accept that as best practice for implementing the function overload facade?
                      – Travis J
                      Jun 1 '12 at 19:11






                    • 2




                      @TravisJ - yes, adaptable function is the way overloads are done in Javascript. Your other option is to use a separately named function with different arguments. If the two implementations have nothing in common, then either is an acceptable practice. If the two implementations are essentially doing the same thing, but just starting with different arguments, then I think it makes your interface more compact to use the adaptable function and it gives you an opportunity to share code between the two related implementations.
                      – jfriend00
                      Jun 1 '12 at 19:14












                    • Added some code examples, explained in both English and in actual code.
                      – jfriend00
                      Oct 26 '14 at 22:49










                    • I am getting an error, unexpected token '=' on the latest version of Safari when I try this resetProgressBar: function(display_errors, lockout = false).
                      – Nick
                      Jul 19 '16 at 2:46












                    • @Nick - Per this ES6 compatibility table, default parameter values should work in Safari 10 and later. Per this MDN page, it says "no support" in Safari. I don't have a Mac so I can't test it out myself. It seems to generally be one of the later implemented ES6 features across many browsers. For example, it doesn't look like it's in iOS9 yet.
                      – jfriend00
                      Jul 19 '16 at 4:15

















                    up vote
                    100
                    down vote



                    accepted










                    There are multiple aspects to argument overloading in Javascript:




                    1. Variable arguments - You can pass different sets of arguments (in both type and quantity) and the function will behave in a way that matches the arguments passed to it.


                    2. Default arguments - You can define a default value for an argument if it is not passed.


                    3. Named arguments - Argument order becomes irrelevant and you just name which arguments you want to pass to the function.



                    Below is a section on each of these categories of argument handling.



                    Variable Arguments



                    Because javascript has no type checking on arguments or required qty of arguments, you can just have one implementation of myFunc() that can adapt to what arguments were passed to it by checking the type, presence or quantity of arguments.



                    jQuery does this all the time. You can make some of the arguments optional or you can branch in your function depending upon what arguments are passed to it.



                    In implementing these types of overloads, you have several different techniques you can use:




                    1. You can check for the presence of any given argument by checking to see if the declared argument name value is undefined.

                    2. You can check the total quantity or arguments with arguments.length.

                    3. You can check the type of any given argument.

                    4. For variable numbers of arguments, you can use the arguments pseudo-array to access any given argument with arguments[i].


                    Here are some examples:



                    Let's look at jQuery's obj.data() method. It supports four different forms of usage:



                    obj.data("key");
                    obj.data("key", value);
                    obj.data();
                    obj.data(object);


                    Each one triggers a different behavior and, without using this dynamic form of overloading, would require four separate functions.



                    Here's how one can discern between all these options in English and then I'll combine them all in code:



                    // get the data element associated with a particular key value
                    obj.data("key");


                    If the first argument passed to .data() is a string and the second argument is undefined, then the caller must be using this form.





                    // set the value associated with a particular key
                    obj.data("key", value);


                    If the second argument is not undefined, then set the value of a particular key.





                    // get all keys/values
                    obj.data();


                    If no arguments are passed, then return all keys/values in a returned object.





                    // set all keys/values from the passed in object
                    obj.data(object);


                    If the type of the first argument is a plain object, then set all keys/values from that object.





                    Here's how you could combine all of those in one set of javascript logic:



                     // 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
                    }
                    },




                    The key to this technique is to make sure that all forms of arguments you want to accept are uniquely identifiable and there is never any confusion about which form the caller is using. This generally requires ordering the arguments appropriately and making sure that there is enough uniqueness in the type and position of the arguments that you can always tell which form is being used.



                    For example, if you have a function that takes three string arguments:



                    obj.query("firstArg", "secondArg", "thirdArg");


                    You can easily make the third argument optional and you can easily detect that condition, but you cannot make only the second argument optional because you can't tell which of these the caller means to be passing because there is no way to identify if the second argument is meant to be the second argument or the second argument was omitted so what's in the second argument's spot is actually the third argument:



                    obj.query("firstArg", "secondArg");
                    obj.query("firstArg", "thirdArg");


                    Since all three arguments are the same type, you can't tell the difference between different arguments so you don't know what the caller intended. With this calling style, only the third argument can be optional. If you wanted to omit the second argument, it would have to be passed as null (or some other detectable value) instead and your code would detect that:



                    obj.query("firstArg", null, "thirdArg");




                    Here's a jQuery example of optional arguments. both arguments are optional and take on default values if not passed:



                    clone: function( dataAndEvents, deepDataAndEvents ) {
                    dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
                    deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;

                    return this.map( function () {
                    return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
                    });
                    },


                    Here's a jQuery example where the argument can be missing or any one of three different types which gives you four different overloads:



                    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;
                    },




                    Named Arguments



                    Other languages (like Python) allow one to pass named arguments as a means of passing only some arguments and making the arguments independent of the order they are passed in. Javascript does not directly support the feature of named arguments. A design pattern that is commonly used in its place is to pass a map of properties/values. This can be done by passing an object with properties and values or in ES6 and above, you could actually pass a Map object itself.



                    Here's a simple ES5 example:



                    jQuery's $.ajax() accepts a form of usage where you just pass it a single parameter which is a regular Javascript object with properties and values. Which properties you pass it determine which arguments/options are being passed to the ajax call. Some may be required, many are optional. Since they are properties on an object, there is no specific order. In fact, there are more than 30 different properties that can be passed on that object, only one (the url) is required.



                    Here's an example:



                    $.ajax({url: "http://www.example.com/somepath", data: myArgs, dataType: "json"}).then(function(result) {
                    // process result here
                    });


                    Inside of the $.ajax() implementation, it can then just interrogate which properties were passed on the incoming object and use those as named arguments. This can be done either with for (prop in obj) or by getting all the properties into an array with Object.keys(obj) and then iterating that array.



                    This technique is used very commonly in Javascript when there are large numbers of arguments and/or many arguments are optional. Note: this puts an onus on the implementating function to make sure that a minimal valid set of arguments is present and to give the caller some debug feedback what is missing if insufficient arguments are passed (probably by throwing an exception with a helpful error message).



                    In an ES6 environment, it is possible to use destructuring to create default properties/values for the above passed object. This is discussed in more detail in this reference article.



                    Here's one example from that article:



                    function selectEntries({ start=0, end=-1, step=1 } = {}) {
                    ···
                    };


                    This creates default properties and values for the start, end and step properties on an object passed to the selectEntries() function.



                    Default values for function arguments



                    In ES6, Javascript adds built-in language support for default values for arguments.



                    For example:



                    function multiply(a, b = 1) {
                    return a*b;
                    }

                    multiply(5); // 5


                    Further description of the ways this can be used here on MDN.






                    share|improve this answer























                    • So I should just stick with an adaptable function and accept that as best practice for implementing the function overload facade?
                      – Travis J
                      Jun 1 '12 at 19:11






                    • 2




                      @TravisJ - yes, adaptable function is the way overloads are done in Javascript. Your other option is to use a separately named function with different arguments. If the two implementations have nothing in common, then either is an acceptable practice. If the two implementations are essentially doing the same thing, but just starting with different arguments, then I think it makes your interface more compact to use the adaptable function and it gives you an opportunity to share code between the two related implementations.
                      – jfriend00
                      Jun 1 '12 at 19:14












                    • Added some code examples, explained in both English and in actual code.
                      – jfriend00
                      Oct 26 '14 at 22:49










                    • I am getting an error, unexpected token '=' on the latest version of Safari when I try this resetProgressBar: function(display_errors, lockout = false).
                      – Nick
                      Jul 19 '16 at 2:46












                    • @Nick - Per this ES6 compatibility table, default parameter values should work in Safari 10 and later. Per this MDN page, it says "no support" in Safari. I don't have a Mac so I can't test it out myself. It seems to generally be one of the later implemented ES6 features across many browsers. For example, it doesn't look like it's in iOS9 yet.
                      – jfriend00
                      Jul 19 '16 at 4:15















                    up vote
                    100
                    down vote



                    accepted







                    up vote
                    100
                    down vote



                    accepted






                    There are multiple aspects to argument overloading in Javascript:




                    1. Variable arguments - You can pass different sets of arguments (in both type and quantity) and the function will behave in a way that matches the arguments passed to it.


                    2. Default arguments - You can define a default value for an argument if it is not passed.


                    3. Named arguments - Argument order becomes irrelevant and you just name which arguments you want to pass to the function.



                    Below is a section on each of these categories of argument handling.



                    Variable Arguments



                    Because javascript has no type checking on arguments or required qty of arguments, you can just have one implementation of myFunc() that can adapt to what arguments were passed to it by checking the type, presence or quantity of arguments.



                    jQuery does this all the time. You can make some of the arguments optional or you can branch in your function depending upon what arguments are passed to it.



                    In implementing these types of overloads, you have several different techniques you can use:




                    1. You can check for the presence of any given argument by checking to see if the declared argument name value is undefined.

                    2. You can check the total quantity or arguments with arguments.length.

                    3. You can check the type of any given argument.

                    4. For variable numbers of arguments, you can use the arguments pseudo-array to access any given argument with arguments[i].


                    Here are some examples:



                    Let's look at jQuery's obj.data() method. It supports four different forms of usage:



                    obj.data("key");
                    obj.data("key", value);
                    obj.data();
                    obj.data(object);


                    Each one triggers a different behavior and, without using this dynamic form of overloading, would require four separate functions.



                    Here's how one can discern between all these options in English and then I'll combine them all in code:



                    // get the data element associated with a particular key value
                    obj.data("key");


                    If the first argument passed to .data() is a string and the second argument is undefined, then the caller must be using this form.





                    // set the value associated with a particular key
                    obj.data("key", value);


                    If the second argument is not undefined, then set the value of a particular key.





                    // get all keys/values
                    obj.data();


                    If no arguments are passed, then return all keys/values in a returned object.





                    // set all keys/values from the passed in object
                    obj.data(object);


                    If the type of the first argument is a plain object, then set all keys/values from that object.





                    Here's how you could combine all of those in one set of javascript logic:



                     // 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
                    }
                    },




                    The key to this technique is to make sure that all forms of arguments you want to accept are uniquely identifiable and there is never any confusion about which form the caller is using. This generally requires ordering the arguments appropriately and making sure that there is enough uniqueness in the type and position of the arguments that you can always tell which form is being used.



                    For example, if you have a function that takes three string arguments:



                    obj.query("firstArg", "secondArg", "thirdArg");


                    You can easily make the third argument optional and you can easily detect that condition, but you cannot make only the second argument optional because you can't tell which of these the caller means to be passing because there is no way to identify if the second argument is meant to be the second argument or the second argument was omitted so what's in the second argument's spot is actually the third argument:



                    obj.query("firstArg", "secondArg");
                    obj.query("firstArg", "thirdArg");


                    Since all three arguments are the same type, you can't tell the difference between different arguments so you don't know what the caller intended. With this calling style, only the third argument can be optional. If you wanted to omit the second argument, it would have to be passed as null (or some other detectable value) instead and your code would detect that:



                    obj.query("firstArg", null, "thirdArg");




                    Here's a jQuery example of optional arguments. both arguments are optional and take on default values if not passed:



                    clone: function( dataAndEvents, deepDataAndEvents ) {
                    dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
                    deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;

                    return this.map( function () {
                    return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
                    });
                    },


                    Here's a jQuery example where the argument can be missing or any one of three different types which gives you four different overloads:



                    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;
                    },




                    Named Arguments



                    Other languages (like Python) allow one to pass named arguments as a means of passing only some arguments and making the arguments independent of the order they are passed in. Javascript does not directly support the feature of named arguments. A design pattern that is commonly used in its place is to pass a map of properties/values. This can be done by passing an object with properties and values or in ES6 and above, you could actually pass a Map object itself.



                    Here's a simple ES5 example:



                    jQuery's $.ajax() accepts a form of usage where you just pass it a single parameter which is a regular Javascript object with properties and values. Which properties you pass it determine which arguments/options are being passed to the ajax call. Some may be required, many are optional. Since they are properties on an object, there is no specific order. In fact, there are more than 30 different properties that can be passed on that object, only one (the url) is required.



                    Here's an example:



                    $.ajax({url: "http://www.example.com/somepath", data: myArgs, dataType: "json"}).then(function(result) {
                    // process result here
                    });


                    Inside of the $.ajax() implementation, it can then just interrogate which properties were passed on the incoming object and use those as named arguments. This can be done either with for (prop in obj) or by getting all the properties into an array with Object.keys(obj) and then iterating that array.



                    This technique is used very commonly in Javascript when there are large numbers of arguments and/or many arguments are optional. Note: this puts an onus on the implementating function to make sure that a minimal valid set of arguments is present and to give the caller some debug feedback what is missing if insufficient arguments are passed (probably by throwing an exception with a helpful error message).



                    In an ES6 environment, it is possible to use destructuring to create default properties/values for the above passed object. This is discussed in more detail in this reference article.



                    Here's one example from that article:



                    function selectEntries({ start=0, end=-1, step=1 } = {}) {
                    ···
                    };


                    This creates default properties and values for the start, end and step properties on an object passed to the selectEntries() function.



                    Default values for function arguments



                    In ES6, Javascript adds built-in language support for default values for arguments.



                    For example:



                    function multiply(a, b = 1) {
                    return a*b;
                    }

                    multiply(5); // 5


                    Further description of the ways this can be used here on MDN.






                    share|improve this answer














                    There are multiple aspects to argument overloading in Javascript:




                    1. Variable arguments - You can pass different sets of arguments (in both type and quantity) and the function will behave in a way that matches the arguments passed to it.


                    2. Default arguments - You can define a default value for an argument if it is not passed.


                    3. Named arguments - Argument order becomes irrelevant and you just name which arguments you want to pass to the function.



                    Below is a section on each of these categories of argument handling.



                    Variable Arguments



                    Because javascript has no type checking on arguments or required qty of arguments, you can just have one implementation of myFunc() that can adapt to what arguments were passed to it by checking the type, presence or quantity of arguments.



                    jQuery does this all the time. You can make some of the arguments optional or you can branch in your function depending upon what arguments are passed to it.



                    In implementing these types of overloads, you have several different techniques you can use:




                    1. You can check for the presence of any given argument by checking to see if the declared argument name value is undefined.

                    2. You can check the total quantity or arguments with arguments.length.

                    3. You can check the type of any given argument.

                    4. For variable numbers of arguments, you can use the arguments pseudo-array to access any given argument with arguments[i].


                    Here are some examples:



                    Let's look at jQuery's obj.data() method. It supports four different forms of usage:



                    obj.data("key");
                    obj.data("key", value);
                    obj.data();
                    obj.data(object);


                    Each one triggers a different behavior and, without using this dynamic form of overloading, would require four separate functions.



                    Here's how one can discern between all these options in English and then I'll combine them all in code:



                    // get the data element associated with a particular key value
                    obj.data("key");


                    If the first argument passed to .data() is a string and the second argument is undefined, then the caller must be using this form.





                    // set the value associated with a particular key
                    obj.data("key", value);


                    If the second argument is not undefined, then set the value of a particular key.





                    // get all keys/values
                    obj.data();


                    If no arguments are passed, then return all keys/values in a returned object.





                    // set all keys/values from the passed in object
                    obj.data(object);


                    If the type of the first argument is a plain object, then set all keys/values from that object.





                    Here's how you could combine all of those in one set of javascript logic:



                     // 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
                    }
                    },




                    The key to this technique is to make sure that all forms of arguments you want to accept are uniquely identifiable and there is never any confusion about which form the caller is using. This generally requires ordering the arguments appropriately and making sure that there is enough uniqueness in the type and position of the arguments that you can always tell which form is being used.



                    For example, if you have a function that takes three string arguments:



                    obj.query("firstArg", "secondArg", "thirdArg");


                    You can easily make the third argument optional and you can easily detect that condition, but you cannot make only the second argument optional because you can't tell which of these the caller means to be passing because there is no way to identify if the second argument is meant to be the second argument or the second argument was omitted so what's in the second argument's spot is actually the third argument:



                    obj.query("firstArg", "secondArg");
                    obj.query("firstArg", "thirdArg");


                    Since all three arguments are the same type, you can't tell the difference between different arguments so you don't know what the caller intended. With this calling style, only the third argument can be optional. If you wanted to omit the second argument, it would have to be passed as null (or some other detectable value) instead and your code would detect that:



                    obj.query("firstArg", null, "thirdArg");




                    Here's a jQuery example of optional arguments. both arguments are optional and take on default values if not passed:



                    clone: function( dataAndEvents, deepDataAndEvents ) {
                    dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
                    deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;

                    return this.map( function () {
                    return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
                    });
                    },


                    Here's a jQuery example where the argument can be missing or any one of three different types which gives you four different overloads:



                    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;
                    },




                    Named Arguments



                    Other languages (like Python) allow one to pass named arguments as a means of passing only some arguments and making the arguments independent of the order they are passed in. Javascript does not directly support the feature of named arguments. A design pattern that is commonly used in its place is to pass a map of properties/values. This can be done by passing an object with properties and values or in ES6 and above, you could actually pass a Map object itself.



                    Here's a simple ES5 example:



                    jQuery's $.ajax() accepts a form of usage where you just pass it a single parameter which is a regular Javascript object with properties and values. Which properties you pass it determine which arguments/options are being passed to the ajax call. Some may be required, many are optional. Since they are properties on an object, there is no specific order. In fact, there are more than 30 different properties that can be passed on that object, only one (the url) is required.



                    Here's an example:



                    $.ajax({url: "http://www.example.com/somepath", data: myArgs, dataType: "json"}).then(function(result) {
                    // process result here
                    });


                    Inside of the $.ajax() implementation, it can then just interrogate which properties were passed on the incoming object and use those as named arguments. This can be done either with for (prop in obj) or by getting all the properties into an array with Object.keys(obj) and then iterating that array.



                    This technique is used very commonly in Javascript when there are large numbers of arguments and/or many arguments are optional. Note: this puts an onus on the implementating function to make sure that a minimal valid set of arguments is present and to give the caller some debug feedback what is missing if insufficient arguments are passed (probably by throwing an exception with a helpful error message).



                    In an ES6 environment, it is possible to use destructuring to create default properties/values for the above passed object. This is discussed in more detail in this reference article.



                    Here's one example from that article:



                    function selectEntries({ start=0, end=-1, step=1 } = {}) {
                    ···
                    };


                    This creates default properties and values for the start, end and step properties on an object passed to the selectEntries() function.



                    Default values for function arguments



                    In ES6, Javascript adds built-in language support for default values for arguments.



                    For example:



                    function multiply(a, b = 1) {
                    return a*b;
                    }

                    multiply(5); // 5


                    Further description of the ways this can be used here on MDN.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Dec 21 '15 at 10:11

























                    answered Jun 1 '12 at 19:02









                    jfriend00

                    422k49534581




                    422k49534581












                    • So I should just stick with an adaptable function and accept that as best practice for implementing the function overload facade?
                      – Travis J
                      Jun 1 '12 at 19:11






                    • 2




                      @TravisJ - yes, adaptable function is the way overloads are done in Javascript. Your other option is to use a separately named function with different arguments. If the two implementations have nothing in common, then either is an acceptable practice. If the two implementations are essentially doing the same thing, but just starting with different arguments, then I think it makes your interface more compact to use the adaptable function and it gives you an opportunity to share code between the two related implementations.
                      – jfriend00
                      Jun 1 '12 at 19:14












                    • Added some code examples, explained in both English and in actual code.
                      – jfriend00
                      Oct 26 '14 at 22:49










                    • I am getting an error, unexpected token '=' on the latest version of Safari when I try this resetProgressBar: function(display_errors, lockout = false).
                      – Nick
                      Jul 19 '16 at 2:46












                    • @Nick - Per this ES6 compatibility table, default parameter values should work in Safari 10 and later. Per this MDN page, it says "no support" in Safari. I don't have a Mac so I can't test it out myself. It seems to generally be one of the later implemented ES6 features across many browsers. For example, it doesn't look like it's in iOS9 yet.
                      – jfriend00
                      Jul 19 '16 at 4:15




















                    • So I should just stick with an adaptable function and accept that as best practice for implementing the function overload facade?
                      – Travis J
                      Jun 1 '12 at 19:11






                    • 2




                      @TravisJ - yes, adaptable function is the way overloads are done in Javascript. Your other option is to use a separately named function with different arguments. If the two implementations have nothing in common, then either is an acceptable practice. If the two implementations are essentially doing the same thing, but just starting with different arguments, then I think it makes your interface more compact to use the adaptable function and it gives you an opportunity to share code between the two related implementations.
                      – jfriend00
                      Jun 1 '12 at 19:14












                    • Added some code examples, explained in both English and in actual code.
                      – jfriend00
                      Oct 26 '14 at 22:49










                    • I am getting an error, unexpected token '=' on the latest version of Safari when I try this resetProgressBar: function(display_errors, lockout = false).
                      – Nick
                      Jul 19 '16 at 2:46












                    • @Nick - Per this ES6 compatibility table, default parameter values should work in Safari 10 and later. Per this MDN page, it says "no support" in Safari. I don't have a Mac so I can't test it out myself. It seems to generally be one of the later implemented ES6 features across many browsers. For example, it doesn't look like it's in iOS9 yet.
                      – jfriend00
                      Jul 19 '16 at 4:15


















                    So I should just stick with an adaptable function and accept that as best practice for implementing the function overload facade?
                    – Travis J
                    Jun 1 '12 at 19:11




                    So I should just stick with an adaptable function and accept that as best practice for implementing the function overload facade?
                    – Travis J
                    Jun 1 '12 at 19:11




                    2




                    2




                    @TravisJ - yes, adaptable function is the way overloads are done in Javascript. Your other option is to use a separately named function with different arguments. If the two implementations have nothing in common, then either is an acceptable practice. If the two implementations are essentially doing the same thing, but just starting with different arguments, then I think it makes your interface more compact to use the adaptable function and it gives you an opportunity to share code between the two related implementations.
                    – jfriend00
                    Jun 1 '12 at 19:14






                    @TravisJ - yes, adaptable function is the way overloads are done in Javascript. Your other option is to use a separately named function with different arguments. If the two implementations have nothing in common, then either is an acceptable practice. If the two implementations are essentially doing the same thing, but just starting with different arguments, then I think it makes your interface more compact to use the adaptable function and it gives you an opportunity to share code between the two related implementations.
                    – jfriend00
                    Jun 1 '12 at 19:14














                    Added some code examples, explained in both English and in actual code.
                    – jfriend00
                    Oct 26 '14 at 22:49




                    Added some code examples, explained in both English and in actual code.
                    – jfriend00
                    Oct 26 '14 at 22:49












                    I am getting an error, unexpected token '=' on the latest version of Safari when I try this resetProgressBar: function(display_errors, lockout = false).
                    – Nick
                    Jul 19 '16 at 2:46






                    I am getting an error, unexpected token '=' on the latest version of Safari when I try this resetProgressBar: function(display_errors, lockout = false).
                    – Nick
                    Jul 19 '16 at 2:46














                    @Nick - Per this ES6 compatibility table, default parameter values should work in Safari 10 and later. Per this MDN page, it says "no support" in Safari. I don't have a Mac so I can't test it out myself. It seems to generally be one of the later implemented ES6 features across many browsers. For example, it doesn't look like it's in iOS9 yet.
                    – jfriend00
                    Jul 19 '16 at 4:15






                    @Nick - Per this ES6 compatibility table, default parameter values should work in Safari 10 and later. Per this MDN page, it says "no support" in Safari. I don't have a Mac so I can't test it out myself. It seems to generally be one of the later implemented ES6 features across many browsers. For example, it doesn't look like it's in iOS9 yet.
                    – jfriend00
                    Jul 19 '16 at 4:15














                    up vote
                    30
                    down vote













                    Overloading a function in JavaScript can be done in many ways. All of them involve a single master function that either performs all the processes, or delegates to sub-functions/processes.



                    One of the most common simple techniques involves a simple switch:



                    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;
                    }
                    }


                    A more elegant technique would be to use an array (or object if you're not making overloads for every argument count):



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


                    That previous example isn't very elegant, anyone could modify fooArr, and it would fail if someone passes in more than 2 arguments to foo, so a better form would be to use a module pattern and a few checks:



                    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;
                    }());


                    Of course your overloads might want to use a dynamic number of parameters, so you could use an object for the fns collection.



                    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;
                    }());




                    My personal preference tends to be the switch, although it does bulk up the master function. A common example of where I'd use this technique would be a accessor/mutator method:



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





                    share|improve this answer























                    • This is a nice example of an alternative :)
                      – Travis J
                      Jun 1 '12 at 19:04






                    • 1




                      Nice, I like that 2nd technique
                      – Nick Rolando
                      Jun 1 '12 at 19:12

















                    up vote
                    30
                    down vote













                    Overloading a function in JavaScript can be done in many ways. All of them involve a single master function that either performs all the processes, or delegates to sub-functions/processes.



                    One of the most common simple techniques involves a simple switch:



                    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;
                    }
                    }


                    A more elegant technique would be to use an array (or object if you're not making overloads for every argument count):



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


                    That previous example isn't very elegant, anyone could modify fooArr, and it would fail if someone passes in more than 2 arguments to foo, so a better form would be to use a module pattern and a few checks:



                    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;
                    }());


                    Of course your overloads might want to use a dynamic number of parameters, so you could use an object for the fns collection.



                    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;
                    }());




                    My personal preference tends to be the switch, although it does bulk up the master function. A common example of where I'd use this technique would be a accessor/mutator method:



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





                    share|improve this answer























                    • This is a nice example of an alternative :)
                      – Travis J
                      Jun 1 '12 at 19:04






                    • 1




                      Nice, I like that 2nd technique
                      – Nick Rolando
                      Jun 1 '12 at 19:12















                    up vote
                    30
                    down vote










                    up vote
                    30
                    down vote









                    Overloading a function in JavaScript can be done in many ways. All of them involve a single master function that either performs all the processes, or delegates to sub-functions/processes.



                    One of the most common simple techniques involves a simple switch:



                    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;
                    }
                    }


                    A more elegant technique would be to use an array (or object if you're not making overloads for every argument count):



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


                    That previous example isn't very elegant, anyone could modify fooArr, and it would fail if someone passes in more than 2 arguments to foo, so a better form would be to use a module pattern and a few checks:



                    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;
                    }());


                    Of course your overloads might want to use a dynamic number of parameters, so you could use an object for the fns collection.



                    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;
                    }());




                    My personal preference tends to be the switch, although it does bulk up the master function. A common example of where I'd use this technique would be a accessor/mutator method:



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





                    share|improve this answer














                    Overloading a function in JavaScript can be done in many ways. All of them involve a single master function that either performs all the processes, or delegates to sub-functions/processes.



                    One of the most common simple techniques involves a simple switch:



                    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;
                    }
                    }


                    A more elegant technique would be to use an array (or object if you're not making overloads for every argument count):



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


                    That previous example isn't very elegant, anyone could modify fooArr, and it would fail if someone passes in more than 2 arguments to foo, so a better form would be to use a module pattern and a few checks:



                    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;
                    }());


                    Of course your overloads might want to use a dynamic number of parameters, so you could use an object for the fns collection.



                    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;
                    }());




                    My personal preference tends to be the switch, although it does bulk up the master function. A common example of where I'd use this technique would be a accessor/mutator method:



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






                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Jul 8 '14 at 1:38

























                    answered Jun 1 '12 at 19:03









                    zzzzBov

                    129k32260305




                    129k32260305












                    • This is a nice example of an alternative :)
                      – Travis J
                      Jun 1 '12 at 19:04






                    • 1




                      Nice, I like that 2nd technique
                      – Nick Rolando
                      Jun 1 '12 at 19:12




















                    • This is a nice example of an alternative :)
                      – Travis J
                      Jun 1 '12 at 19:04






                    • 1




                      Nice, I like that 2nd technique
                      – Nick Rolando
                      Jun 1 '12 at 19:12


















                    This is a nice example of an alternative :)
                    – Travis J
                    Jun 1 '12 at 19:04




                    This is a nice example of an alternative :)
                    – Travis J
                    Jun 1 '12 at 19:04




                    1




                    1




                    Nice, I like that 2nd technique
                    – Nick Rolando
                    Jun 1 '12 at 19:12






                    Nice, I like that 2nd technique
                    – Nick Rolando
                    Jun 1 '12 at 19:12












                    up vote
                    5
                    down vote













                    You cannot do method overloading in strict sense. Not like the way it is supported in java or c#.



                    The issue is that JavaScript does NOT natively support method overloading. So, if it sees/parses two or more functions with a same names it’ll just consider the last defined function and overwrite the previous ones.



                    One of the way I think is suitable for most of the case is follows -



                    Lets say you have method



                    function foo(x)
                    {
                    }


                    Instead of overloading method which is not possible in javascript you can define a new method



                    fooNew(x,y,z)
                    {
                    }


                    and then modify the 1st function as follows -



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


                    If you have many such overloaded method consider using switch than just if-else statements.



                    (more details)






                    share|improve this answer



























                      up vote
                      5
                      down vote













                      You cannot do method overloading in strict sense. Not like the way it is supported in java or c#.



                      The issue is that JavaScript does NOT natively support method overloading. So, if it sees/parses two or more functions with a same names it’ll just consider the last defined function and overwrite the previous ones.



                      One of the way I think is suitable for most of the case is follows -



                      Lets say you have method



                      function foo(x)
                      {
                      }


                      Instead of overloading method which is not possible in javascript you can define a new method



                      fooNew(x,y,z)
                      {
                      }


                      and then modify the 1st function as follows -



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


                      If you have many such overloaded method consider using switch than just if-else statements.



                      (more details)






                      share|improve this answer

























                        up vote
                        5
                        down vote










                        up vote
                        5
                        down vote









                        You cannot do method overloading in strict sense. Not like the way it is supported in java or c#.



                        The issue is that JavaScript does NOT natively support method overloading. So, if it sees/parses two or more functions with a same names it’ll just consider the last defined function and overwrite the previous ones.



                        One of the way I think is suitable for most of the case is follows -



                        Lets say you have method



                        function foo(x)
                        {
                        }


                        Instead of overloading method which is not possible in javascript you can define a new method



                        fooNew(x,y,z)
                        {
                        }


                        and then modify the 1st function as follows -



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


                        If you have many such overloaded method consider using switch than just if-else statements.



                        (more details)






                        share|improve this answer














                        You cannot do method overloading in strict sense. Not like the way it is supported in java or c#.



                        The issue is that JavaScript does NOT natively support method overloading. So, if it sees/parses two or more functions with a same names it’ll just consider the last defined function and overwrite the previous ones.



                        One of the way I think is suitable for most of the case is follows -



                        Lets say you have method



                        function foo(x)
                        {
                        }


                        Instead of overloading method which is not possible in javascript you can define a new method



                        fooNew(x,y,z)
                        {
                        }


                        and then modify the 1st function as follows -



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


                        If you have many such overloaded method consider using switch than just if-else statements.



                        (more details)







                        share|improve this answer














                        share|improve this answer



                        share|improve this answer








                        edited Sep 13 '14 at 14:51

























                        answered Sep 13 '14 at 6:45









                        Aniket Thakur

                        40.5k23181202




                        40.5k23181202






















                            up vote
                            4
                            down vote













                            I am using a bit different overloading approach based on arguments number.
                            However i believe John Fawcett's approach is also good.
                            Here the example, code based on John Resig's (jQuery's Author) explanations.



                            // 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);
                            }
                            };
                            }


                            usability:



                            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 :)





                            share|improve this answer

























                              up vote
                              4
                              down vote













                              I am using a bit different overloading approach based on arguments number.
                              However i believe John Fawcett's approach is also good.
                              Here the example, code based on John Resig's (jQuery's Author) explanations.



                              // 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);
                              }
                              };
                              }


                              usability:



                              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 :)





                              share|improve this answer























                                up vote
                                4
                                down vote










                                up vote
                                4
                                down vote









                                I am using a bit different overloading approach based on arguments number.
                                However i believe John Fawcett's approach is also good.
                                Here the example, code based on John Resig's (jQuery's Author) explanations.



                                // 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);
                                }
                                };
                                }


                                usability:



                                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 :)





                                share|improve this answer












                                I am using a bit different overloading approach based on arguments number.
                                However i believe John Fawcett's approach is also good.
                                Here the example, code based on John Resig's (jQuery's Author) explanations.



                                // 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);
                                }
                                };
                                }


                                usability:



                                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 :)






                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered Dec 23 '12 at 9:21









                                Valentin Rusk

                                614312




                                614312






















                                    up vote
                                    3
                                    down vote













                                    I tried to develop an elegant solution to this problem described here. And you can find the demo here. The usage looks like this:



                                    var out = def({
                                    'int': function(a) {
                                    alert('Here is int '+a);
                                    },

                                    'float': function(a) {
                                    alert('Here is float '+a);
                                    },

                                    'string': function(a) {
                                    alert('Here is string '+a);
                                    },

                                    'int,string': function(a, b) {
                                    alert('Here is an int '+a+' and a string '+b);
                                    },
                                    'default': function(obj) {
                                    alert('Here is some other value '+ obj);
                                    }

                                    });

                                    out('ten');
                                    out(1);
                                    out(2, 'robot');
                                    out(2.5);
                                    out(true);


                                    The methods used to achieve this:



                                    var def = function(functions, parent) {
                                    return function() {
                                    var types = ;
                                    var args = ;
                                    eachArg(arguments, function(i, elem) {
                                    args.push(elem);
                                    types.push(whatis(elem));
                                    });
                                    if(functions.hasOwnProperty(types.join())) {
                                    return functions[types.join()].apply(parent, args);
                                    } else {
                                    if (typeof functions === 'function')
                                    return functions.apply(parent, args);
                                    if (functions.hasOwnProperty('default'))
                                    return functions['default'].apply(parent, args);
                                    }
                                    };
                                    };

                                    var eachArg = function(args, fn) {
                                    var i = 0;
                                    while (args.hasOwnProperty(i)) {
                                    if(fn !== undefined)
                                    fn(i, args[i]);
                                    i++;
                                    }
                                    return i-1;
                                    };

                                    var whatis = function(val) {

                                    if(val === undefined)
                                    return 'undefined';
                                    if(val === null)
                                    return 'null';

                                    var type = typeof val;

                                    if(type === 'object') {
                                    if(val.hasOwnProperty('length') && val.hasOwnProperty('push'))
                                    return 'array';
                                    if(val.hasOwnProperty('getDate') && val.hasOwnProperty('toLocaleTimeString'))
                                    return 'date';
                                    if(val.hasOwnProperty('toExponential'))
                                    type = 'number';
                                    if(val.hasOwnProperty('substring') && val.hasOwnProperty('length'))
                                    return 'string';
                                    }

                                    if(type === 'number') {
                                    if(val.toString().indexOf('.') > 0)
                                    return 'float';
                                    else
                                    return 'int';
                                    }

                                    return type;
                                    };





                                    share|improve this answer



















                                    • 1




                                      A function to handle the inputs, very clever.
                                      – Travis J
                                      Apr 10 '13 at 1:23















                                    up vote
                                    3
                                    down vote













                                    I tried to develop an elegant solution to this problem described here. And you can find the demo here. The usage looks like this:



                                    var out = def({
                                    'int': function(a) {
                                    alert('Here is int '+a);
                                    },

                                    'float': function(a) {
                                    alert('Here is float '+a);
                                    },

                                    'string': function(a) {
                                    alert('Here is string '+a);
                                    },

                                    'int,string': function(a, b) {
                                    alert('Here is an int '+a+' and a string '+b);
                                    },
                                    'default': function(obj) {
                                    alert('Here is some other value '+ obj);
                                    }

                                    });

                                    out('ten');
                                    out(1);
                                    out(2, 'robot');
                                    out(2.5);
                                    out(true);


                                    The methods used to achieve this:



                                    var def = function(functions, parent) {
                                    return function() {
                                    var types = ;
                                    var args = ;
                                    eachArg(arguments, function(i, elem) {
                                    args.push(elem);
                                    types.push(whatis(elem));
                                    });
                                    if(functions.hasOwnProperty(types.join())) {
                                    return functions[types.join()].apply(parent, args);
                                    } else {
                                    if (typeof functions === 'function')
                                    return functions.apply(parent, args);
                                    if (functions.hasOwnProperty('default'))
                                    return functions['default'].apply(parent, args);
                                    }
                                    };
                                    };

                                    var eachArg = function(args, fn) {
                                    var i = 0;
                                    while (args.hasOwnProperty(i)) {
                                    if(fn !== undefined)
                                    fn(i, args[i]);
                                    i++;
                                    }
                                    return i-1;
                                    };

                                    var whatis = function(val) {

                                    if(val === undefined)
                                    return 'undefined';
                                    if(val === null)
                                    return 'null';

                                    var type = typeof val;

                                    if(type === 'object') {
                                    if(val.hasOwnProperty('length') && val.hasOwnProperty('push'))
                                    return 'array';
                                    if(val.hasOwnProperty('getDate') && val.hasOwnProperty('toLocaleTimeString'))
                                    return 'date';
                                    if(val.hasOwnProperty('toExponential'))
                                    type = 'number';
                                    if(val.hasOwnProperty('substring') && val.hasOwnProperty('length'))
                                    return 'string';
                                    }

                                    if(type === 'number') {
                                    if(val.toString().indexOf('.') > 0)
                                    return 'float';
                                    else
                                    return 'int';
                                    }

                                    return type;
                                    };





                                    share|improve this answer



















                                    • 1




                                      A function to handle the inputs, very clever.
                                      – Travis J
                                      Apr 10 '13 at 1:23













                                    up vote
                                    3
                                    down vote










                                    up vote
                                    3
                                    down vote









                                    I tried to develop an elegant solution to this problem described here. And you can find the demo here. The usage looks like this:



                                    var out = def({
                                    'int': function(a) {
                                    alert('Here is int '+a);
                                    },

                                    'float': function(a) {
                                    alert('Here is float '+a);
                                    },

                                    'string': function(a) {
                                    alert('Here is string '+a);
                                    },

                                    'int,string': function(a, b) {
                                    alert('Here is an int '+a+' and a string '+b);
                                    },
                                    'default': function(obj) {
                                    alert('Here is some other value '+ obj);
                                    }

                                    });

                                    out('ten');
                                    out(1);
                                    out(2, 'robot');
                                    out(2.5);
                                    out(true);


                                    The methods used to achieve this:



                                    var def = function(functions, parent) {
                                    return function() {
                                    var types = ;
                                    var args = ;
                                    eachArg(arguments, function(i, elem) {
                                    args.push(elem);
                                    types.push(whatis(elem));
                                    });
                                    if(functions.hasOwnProperty(types.join())) {
                                    return functions[types.join()].apply(parent, args);
                                    } else {
                                    if (typeof functions === 'function')
                                    return functions.apply(parent, args);
                                    if (functions.hasOwnProperty('default'))
                                    return functions['default'].apply(parent, args);
                                    }
                                    };
                                    };

                                    var eachArg = function(args, fn) {
                                    var i = 0;
                                    while (args.hasOwnProperty(i)) {
                                    if(fn !== undefined)
                                    fn(i, args[i]);
                                    i++;
                                    }
                                    return i-1;
                                    };

                                    var whatis = function(val) {

                                    if(val === undefined)
                                    return 'undefined';
                                    if(val === null)
                                    return 'null';

                                    var type = typeof val;

                                    if(type === 'object') {
                                    if(val.hasOwnProperty('length') && val.hasOwnProperty('push'))
                                    return 'array';
                                    if(val.hasOwnProperty('getDate') && val.hasOwnProperty('toLocaleTimeString'))
                                    return 'date';
                                    if(val.hasOwnProperty('toExponential'))
                                    type = 'number';
                                    if(val.hasOwnProperty('substring') && val.hasOwnProperty('length'))
                                    return 'string';
                                    }

                                    if(type === 'number') {
                                    if(val.toString().indexOf('.') > 0)
                                    return 'float';
                                    else
                                    return 'int';
                                    }

                                    return type;
                                    };





                                    share|improve this answer














                                    I tried to develop an elegant solution to this problem described here. And you can find the demo here. The usage looks like this:



                                    var out = def({
                                    'int': function(a) {
                                    alert('Here is int '+a);
                                    },

                                    'float': function(a) {
                                    alert('Here is float '+a);
                                    },

                                    'string': function(a) {
                                    alert('Here is string '+a);
                                    },

                                    'int,string': function(a, b) {
                                    alert('Here is an int '+a+' and a string '+b);
                                    },
                                    'default': function(obj) {
                                    alert('Here is some other value '+ obj);
                                    }

                                    });

                                    out('ten');
                                    out(1);
                                    out(2, 'robot');
                                    out(2.5);
                                    out(true);


                                    The methods used to achieve this:



                                    var def = function(functions, parent) {
                                    return function() {
                                    var types = ;
                                    var args = ;
                                    eachArg(arguments, function(i, elem) {
                                    args.push(elem);
                                    types.push(whatis(elem));
                                    });
                                    if(functions.hasOwnProperty(types.join())) {
                                    return functions[types.join()].apply(parent, args);
                                    } else {
                                    if (typeof functions === 'function')
                                    return functions.apply(parent, args);
                                    if (functions.hasOwnProperty('default'))
                                    return functions['default'].apply(parent, args);
                                    }
                                    };
                                    };

                                    var eachArg = function(args, fn) {
                                    var i = 0;
                                    while (args.hasOwnProperty(i)) {
                                    if(fn !== undefined)
                                    fn(i, args[i]);
                                    i++;
                                    }
                                    return i-1;
                                    };

                                    var whatis = function(val) {

                                    if(val === undefined)
                                    return 'undefined';
                                    if(val === null)
                                    return 'null';

                                    var type = typeof val;

                                    if(type === 'object') {
                                    if(val.hasOwnProperty('length') && val.hasOwnProperty('push'))
                                    return 'array';
                                    if(val.hasOwnProperty('getDate') && val.hasOwnProperty('toLocaleTimeString'))
                                    return 'date';
                                    if(val.hasOwnProperty('toExponential'))
                                    type = 'number';
                                    if(val.hasOwnProperty('substring') && val.hasOwnProperty('length'))
                                    return 'string';
                                    }

                                    if(type === 'number') {
                                    if(val.toString().indexOf('.') > 0)
                                    return 'float';
                                    else
                                    return 'int';
                                    }

                                    return type;
                                    };






                                    share|improve this answer














                                    share|improve this answer



                                    share|improve this answer








                                    edited Apr 10 '13 at 9:59

























                                    answered Apr 10 '13 at 1:22









                                    stamat

                                    9291317




                                    9291317








                                    • 1




                                      A function to handle the inputs, very clever.
                                      – Travis J
                                      Apr 10 '13 at 1:23














                                    • 1




                                      A function to handle the inputs, very clever.
                                      – Travis J
                                      Apr 10 '13 at 1:23








                                    1




                                    1




                                    A function to handle the inputs, very clever.
                                    – Travis J
                                    Apr 10 '13 at 1:23




                                    A function to handle the inputs, very clever.
                                    – Travis J
                                    Apr 10 '13 at 1:23










                                    up vote
                                    3
                                    down vote













                                    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"





                                    share|improve this answer



























                                      up vote
                                      3
                                      down vote













                                      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"





                                      share|improve this answer

























                                        up vote
                                        3
                                        down vote










                                        up vote
                                        3
                                        down vote









                                        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"





                                        share|improve this answer














                                        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"






                                        share|improve this answer














                                        share|improve this answer



                                        share|improve this answer








                                        edited Sep 7 '13 at 21:48









                                        Nate-Wilkins

                                        4,38933757




                                        4,38933757










                                        answered Jun 23 '12 at 22:05









                                        John Fawcett

                                        449312




                                        449312






















                                            up vote
                                            3
                                            down vote













                                            In javascript you can implement the function just once and invoke the function without the parameters myFunc() You then check to see if options is 'undefined'



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





                                            share|improve this answer



























                                              up vote
                                              3
                                              down vote













                                              In javascript you can implement the function just once and invoke the function without the parameters myFunc() You then check to see if options is 'undefined'



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





                                              share|improve this answer

























                                                up vote
                                                3
                                                down vote










                                                up vote
                                                3
                                                down vote









                                                In javascript you can implement the function just once and invoke the function without the parameters myFunc() You then check to see if options is 'undefined'



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





                                                share|improve this answer














                                                In javascript you can implement the function just once and invoke the function without the parameters myFunc() You then check to see if options is 'undefined'



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






                                                share|improve this answer














                                                share|improve this answer



                                                share|improve this answer








                                                edited Mar 21 '14 at 19:50









                                                daniel1426

                                                127113




                                                127113










                                                answered Jun 1 '12 at 19:01









                                                Murtnowski

                                                1,8521131




                                                1,8521131






















                                                    up vote
                                                    2
                                                    down vote













                                                    Check this out:



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



                                                    Basically in your class, you number your functions that you want to be overloaded and then with one function call you add function overloading, fast and easy.






                                                    share|improve this answer

























                                                      up vote
                                                      2
                                                      down vote













                                                      Check this out:



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



                                                      Basically in your class, you number your functions that you want to be overloaded and then with one function call you add function overloading, fast and easy.






                                                      share|improve this answer























                                                        up vote
                                                        2
                                                        down vote










                                                        up vote
                                                        2
                                                        down vote









                                                        Check this out:



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



                                                        Basically in your class, you number your functions that you want to be overloaded and then with one function call you add function overloading, fast and easy.






                                                        share|improve this answer












                                                        Check this out:



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



                                                        Basically in your class, you number your functions that you want to be overloaded and then with one function call you add function overloading, fast and easy.







                                                        share|improve this answer












                                                        share|improve this answer



                                                        share|improve this answer










                                                        answered Dec 3 '13 at 8:44









                                                        Ralph

                                                        368110




                                                        368110






















                                                            up vote
                                                            2
                                                            down vote













                                                            Since JavaScript doesn't have function overload options object can be used instead. If there are one or two required arguments, it's better to keep them separate from the options object. Here is an example on how to use options object and populated values to default value in case if value was not passed in options object.



                                                            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 + "}";


                                                            }



                                                            here is an example on how to use options object






                                                            share|improve this answer

























                                                              up vote
                                                              2
                                                              down vote













                                                              Since JavaScript doesn't have function overload options object can be used instead. If there are one or two required arguments, it's better to keep them separate from the options object. Here is an example on how to use options object and populated values to default value in case if value was not passed in options object.



                                                              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 + "}";


                                                              }



                                                              here is an example on how to use options object






                                                              share|improve this answer























                                                                up vote
                                                                2
                                                                down vote










                                                                up vote
                                                                2
                                                                down vote









                                                                Since JavaScript doesn't have function overload options object can be used instead. If there are one or two required arguments, it's better to keep them separate from the options object. Here is an example on how to use options object and populated values to default value in case if value was not passed in options object.



                                                                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 + "}";


                                                                }



                                                                here is an example on how to use options object






                                                                share|improve this answer












                                                                Since JavaScript doesn't have function overload options object can be used instead. If there are one or two required arguments, it's better to keep them separate from the options object. Here is an example on how to use options object and populated values to default value in case if value was not passed in options object.



                                                                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 + "}";


                                                                }



                                                                here is an example on how to use options object







                                                                share|improve this answer












                                                                share|improve this answer



                                                                share|improve this answer










                                                                answered Jan 9 '14 at 2:44









                                                                Vlad Bezden

                                                                26.6k10119110




                                                                26.6k10119110






















                                                                    up vote
                                                                    2
                                                                    down vote













                                                                    For this you need to create a function that adds the function to an object, then it will execute depending on the amount of arguments you send to the function:



                                                                    <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>





                                                                    share|improve this answer

























                                                                      up vote
                                                                      2
                                                                      down vote













                                                                      For this you need to create a function that adds the function to an object, then it will execute depending on the amount of arguments you send to the function:



                                                                      <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>





                                                                      share|improve this answer























                                                                        up vote
                                                                        2
                                                                        down vote










                                                                        up vote
                                                                        2
                                                                        down vote









                                                                        For this you need to create a function that adds the function to an object, then it will execute depending on the amount of arguments you send to the function:



                                                                        <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>





                                                                        share|improve this answer












                                                                        For this you need to create a function that adds the function to an object, then it will execute depending on the amount of arguments you send to the function:



                                                                        <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>






                                                                        share|improve this answer












                                                                        share|improve this answer



                                                                        share|improve this answer










                                                                        answered Aug 26 '14 at 20:40









                                                                        Max Cabrera

                                                                        10114




                                                                        10114






















                                                                            up vote
                                                                            2
                                                                            down vote













                                                                            No Problem with Overloading in JS , The pb how to maintain a clean code when overloading function ?



                                                                            You can use a forward to have clean code , based on two things:




                                                                            1. Number of arguments (when calling the function).


                                                                            2. Type of arguments (when callin the function)



                                                                                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 ....







                                                                            share|improve this answer

























                                                                              up vote
                                                                              2
                                                                              down vote













                                                                              No Problem with Overloading in JS , The pb how to maintain a clean code when overloading function ?



                                                                              You can use a forward to have clean code , based on two things:




                                                                              1. Number of arguments (when calling the function).


                                                                              2. Type of arguments (when callin the function)



                                                                                  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 ....







                                                                              share|improve this answer























                                                                                up vote
                                                                                2
                                                                                down vote










                                                                                up vote
                                                                                2
                                                                                down vote









                                                                                No Problem with Overloading in JS , The pb how to maintain a clean code when overloading function ?



                                                                                You can use a forward to have clean code , based on two things:




                                                                                1. Number of arguments (when calling the function).


                                                                                2. Type of arguments (when callin the function)



                                                                                    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 ....







                                                                                share|improve this answer












                                                                                No Problem with Overloading in JS , The pb how to maintain a clean code when overloading function ?



                                                                                You can use a forward to have clean code , based on two things:




                                                                                1. Number of arguments (when calling the function).


                                                                                2. Type of arguments (when callin the function)



                                                                                    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 ....








                                                                                share|improve this answer












                                                                                share|improve this answer



                                                                                share|improve this answer










                                                                                answered Jul 19 '16 at 8:09









                                                                                Abdennour TOUMI

                                                                                31.7k15137151




                                                                                31.7k15137151






















                                                                                    up vote
                                                                                    0
                                                                                    down vote













                                                                                    I like to add sub functions within a parent function to achieve the ability to differentiate between argument groups for the same functionality.



                                                                                    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;
                                                                                    };





                                                                                    share|improve this answer

























                                                                                      up vote
                                                                                      0
                                                                                      down vote













                                                                                      I like to add sub functions within a parent function to achieve the ability to differentiate between argument groups for the same functionality.



                                                                                      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;
                                                                                      };





                                                                                      share|improve this answer























                                                                                        up vote
                                                                                        0
                                                                                        down vote










                                                                                        up vote
                                                                                        0
                                                                                        down vote









                                                                                        I like to add sub functions within a parent function to achieve the ability to differentiate between argument groups for the same functionality.



                                                                                        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;
                                                                                        };





                                                                                        share|improve this answer












                                                                                        I like to add sub functions within a parent function to achieve the ability to differentiate between argument groups for the same functionality.



                                                                                        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;
                                                                                        };






                                                                                        share|improve this answer












                                                                                        share|improve this answer



                                                                                        share|improve this answer










                                                                                        answered Jun 17 '13 at 18:23









                                                                                        ogc-nick

                                                                                        3,78911843




                                                                                        3,78911843






















                                                                                            up vote
                                                                                            0
                                                                                            down vote













                                                                                            What you are trying to achieve is best done using the function's local arguments variable.



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

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


                                                                                            You can find a better explanation of how this works here.






                                                                                            share|improve this answer





















                                                                                            • And what about collision detection? This is a nice way to use parameterless functions or to check for existence, but not really best practice when it comes to overloading.
                                                                                              – Travis J
                                                                                              Oct 8 '13 at 14:10

















                                                                                            up vote
                                                                                            0
                                                                                            down vote













                                                                                            What you are trying to achieve is best done using the function's local arguments variable.



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

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


                                                                                            You can find a better explanation of how this works here.






                                                                                            share|improve this answer





















                                                                                            • And what about collision detection? This is a nice way to use parameterless functions or to check for existence, but not really best practice when it comes to overloading.
                                                                                              – Travis J
                                                                                              Oct 8 '13 at 14:10















                                                                                            up vote
                                                                                            0
                                                                                            down vote










                                                                                            up vote
                                                                                            0
                                                                                            down vote









                                                                                            What you are trying to achieve is best done using the function's local arguments variable.



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

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


                                                                                            You can find a better explanation of how this works here.






                                                                                            share|improve this answer












                                                                                            What you are trying to achieve is best done using the function's local arguments variable.



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

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


                                                                                            You can find a better explanation of how this works here.







                                                                                            share|improve this answer












                                                                                            share|improve this answer



                                                                                            share|improve this answer










                                                                                            answered Oct 8 '13 at 5:35









                                                                                            jbarnett

                                                                                            83446




                                                                                            83446












                                                                                            • And what about collision detection? This is a nice way to use parameterless functions or to check for existence, but not really best practice when it comes to overloading.
                                                                                              – Travis J
                                                                                              Oct 8 '13 at 14:10




















                                                                                            • And what about collision detection? This is a nice way to use parameterless functions or to check for existence, but not really best practice when it comes to overloading.
                                                                                              – Travis J
                                                                                              Oct 8 '13 at 14:10


















                                                                                            And what about collision detection? This is a nice way to use parameterless functions or to check for existence, but not really best practice when it comes to overloading.
                                                                                            – Travis J
                                                                                            Oct 8 '13 at 14:10






                                                                                            And what about collision detection? This is a nice way to use parameterless functions or to check for existence, but not really best practice when it comes to overloading.
                                                                                            – Travis J
                                                                                            Oct 8 '13 at 14:10







                                                                                            protected by Tushar Gupta Oct 4 '14 at 14:52



                                                                                            Thank you for your interest in this question.
                                                                                            Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                                                                                            Would you like to answer one of these unanswered questions instead?



                                                                                            這個網誌中的熱門文章

                                                                                            Tangent Lines Diagram Along Smooth Curve

                                                                                            Yusuf al-Mu'taman ibn Hud

                                                                                            Zucchini