options help define how a command should behave. Some may be optional. arguments tell commands what object to operate on.
An “options object” is a programming pattern that you can use to pass any number of named arguments to a function. Rather than using an ordered list of arguments, you simply pass one argument, which is an object containing named keys for all of your options.
Multiple ArgumentsYou can actually have your variable arguments along with other arguments. That is, you can pass your method a double, an int, and then a String using varargs.
Like many of the others, I often prefer passing an options object
to a function instead of passing a long list of parameters, but it really depends on the exact context.
I use code readability as the litmus test.
For instance, if I have this function call:
checkStringLength(inputStr, 10);
I think that code is quite readable the way it is and passing individual parameters is just fine.
On the other hand, there are functions with calls like this:
initiateTransferProtocol("http", false, 150, 90, null, true, 18);
Completely unreadable unless you do some research. On the other hand, this code reads well:
initiateTransferProtocol({
"protocol": "http",
"sync": false,
"delayBetweenRetries": 150,
"randomVarianceBetweenRetries": 90,
"retryCallback": null,
"log": true,
"maxRetries": 18
});
It is more of an art than a science, but if I had to name rules of thumb:
Use an options parameter if:
Multiple arguments are mostly for obligatory parameters. There's nothing wrong with them.
If you have optional parameters, it gets complicated. If one of them relies on the others, so that they have a certain order (e.g. the fourth one needs the third one), you still should use multiple arguments. Nearly all native EcmaScript and DOM-methods work like this. A good example is the open
method of XMLHTTPrequests, where the last 3 arguments are optional - the rule is like "no password without a user" (see also MDN docs).
Option objects come in handy in two cases:
undefined
s). In your case, I'd recommend map(nodeList, callback, options)
. nodelist
and callback
are required, the other three arguments come in only occasionally and have reasonable defaults.
Another example is JSON.stringify
. You might want to use the space
parameter without passing a replacer
function - then you have to call …, null, 4)
. An arguments object might have been better, although its not really reasonable for only 2 parameters.
Using the 'options as an object' approach is going to be best. You don't have to worry about the order of the properties and there's more flexibility in what data gets passed (optional parameters for example)
Creating an object also means the options could be easily used on multiple functions:
options={
nodeList:...,
callback:...,
thisObject:...,
fromIndex:...,
toIndex:...
}
function1(options){
alert(options.nodeList);
}
function2(options){
alert(options.fromIndex);
}
It can be good to use both. If your function has one or two required parameters and a bunch of optional ones, make the first two parameters required and the third an optional options hash.
In your example, I'd do map(nodeList, callback, options)
. Nodelist and callback are required, it's fairly easy to tell what's happening just by reading a call to it, and it's like existing map functions. Any other options can be passed as an optional third parameter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With