One thing that comes to my mind is method overloading. Technically, this is not supported in JavaScript, but there is a way to implement something like this. John Resig has an article about this on his blog: http://ejohn.org/blog/javascript-method-overloading/
Also, here is my implementation, which is very similar to and inspired by John Resig:
var createFunction = (function(){ var store = {}; return function(that, name, func) { var scope, funcs, match; scope = store[that] || (store[that] = {}); funcs = scope[name] || (scope[name] = {}); funcs[func.length] = func; that[name] = function(){ match = funcs[arguments.length]; if (match !== undefined) { return match.apply(that, arguments); } else { throw "no function with " + arguments.length + " arguments defined"; } }; }; }());
This allows you to define the same function several times with a different number of arguments each time:
createFunction(window, "doSomething", function (arg1, arg2, callback) { console.log(arg1 + " / " + arg2 + " / " + callback); }); createFunction(window, "doSomething", function (arg1, callback) { doSomething(arg1, null, callback); });
This piece of code defines the global doSomething function, once with three and once with two arguments. As you can see, the first drawback of this method is that you must provide the object to which the functions are attached, you cannot just say "define the function right here." In addition, function declarations are a bit more complicated than before. But now you can call your function with a different number of arguments and get the correct result without using repetitions of if..else structures:
doSomething("he", function(){});
So far, only the number of arguments matters, but I can think of it to also respond to different types of data, so the following can also be distinguished:
function doSomething(opt1, opt2, callback){
However, this is probably not the best way, but in certain circumstances it may be convenient. For a large number of optional arguments, I personally like the answer of Pumbaa80 to include these parameters in one required object argument.