There's really two ways to do what you are describing, but neither of them 100% meets your requirements . . .
1) Use a required options
array or object to hold optional parameters
In this approach, you would have a parameter "on call" to hold 0 or more parameters in addition to the required ones:
function performAction(URL, options, successCallback, errorCallback) {...}
This would support your desired functionality, but would force the user to provide, at a minimum, an empty Array
or Object
as the second parameter:
performAction(someURL, [], function1, function2);
performAction(someURL, [foo, bar], function1, function2);
performAction(someURL, {}, function1, function2);
performAction(someURL, {foo: "abc", bar: "xyz"}, function1, function2);
2) Use the newer "rest parameters" provided by ES6
This approach would allow you to make any additional parameters truly optional (no empty value needed), however, rest parameters are required to be the last parameter in the function:
function performAction(URL, successCallback, errorCallback, ...options) {...}
So, while you would not get the order of parameters that want, it would meet your desire to have the optional parameters be truly optional:
performAction(someURL, function1, function2);
performAction(someURL, function1, function2, foo);
performAction(someURL, function1, function2, foo, bar, baz);
Any additional parameters will be pulled together and stored in an array, that can be accessed within the function. See more on rest parameters here on MDN.
The other drawback to this approach is that ES6 is still being rolled out into browsers, so it is not supported in browsers just yet. You can use a transpiler like Babel to make it understandable to those browsers, but that does add some complexity to this approach.
UPDATE: Technically, there is also a 3rd option to work with the arguments
object that is built into JavaScript functions (more info here on MDN), but this would be messy. You would need to define the function with the three required parameters:
function performAction(URL, successCallback, errorCallback) {...}
. . . but then call the function with (potentially) more than the three expected arguments:
performAction(someURL, function1, function2);
performAction(someURL, foo, function1, function2);
performAction(someURL, foo, bar, baz, function1, function2);
The function would then need to access the parameters in a complicated way . . . you'd actually need to redefine the last two parameter values, based on their placement in the arguments
object:
var argLength = arguments.length;
successCallback = arguments[argLength - 2];
errorCallback= arguments[argLength - 1];
To access any of the remaining values, you would either need to:
- iterate through them using a starting index of 1 and running through them while the index was less than
argLength - 2
, or
- convert the
arguments
object into an array and slice
the values out into their own array
NOTE: I do NOT recommend this approach, but, technically, it is possible.