Multiple arguments vs. options object Multiple arguments vs. options object json json

Multiple arguments vs. options object

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:

  • You have more than four parameters
  • Any of the parameters are optional
  • You've ever had to look up the function to figure out what parameters it takes
  • If someone ever tries to strangle you while screaming "ARRRRRG!"

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:

  • You've got so many parameters that it gets confusing: The "naming" will help you, you don't have to worry about the order of them (especially if they may change)
  • You've got optional parameters. The objects are very flexible, and without any ordering you just pass the things you need and nothing else (or undefineds).

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