Best practices for JavaScript function parameters

  • The problem with passing an object as a parameter to a function is that it’s not clear what values you should put into it.
  • One common thing in FP is to partially apply your functions, which is much harder to do if your function takes its parameters as an object.
  • While separate parameters are a good starting point, we run into trouble as soon as the function has optional parameters.
  • For functions with a single optional parameter, the solution is simple:

    Best practice: optionals come last

    However, if we have more than one optional parameter, the problem is… what if we only need to pass one optional parameter?

  • You can pass in parameters easily as an object, but the properties for the object can be easily seen from the function’s signature.

From time to time, people ask things like “should I use objects to pass function arguments”. I’m sure you recognize the pattern, as it’s common with many libraries:

@craigtaub: Great rules to live by when handling function parameters.
#nodejs #webdev #javascript #reactjs

From time to time, people ask things like “should I use objects to pass function arguments”. I’m sure you recognize the pattern, as it’s common with many libraries:

But I would say this is not actually such a good idea.

Let’s take a look at the best practices for defining function parameter lists in JavaScript.

Clarity is the goal

The problem with passing an object as a parameter to a function is that it’s not clear what values you should put into it.

With libraries like jQuery, it isn’t a big deal – just look at the docs and oh there you go. But in the custom code you’ll run into at work? Just look at the docs… oh wait, what docs? Yeah.

As much as documentation would be nice, custom codebases never have the kind of docs you’d need. If you need to figure out what parameters some function takes, you’re going to have to dig up the source code for it.

This problem is best illustrated by an example. Here’s a function used to throttle some other function:

(Original code borrowed from Remy Sharp)

Quick! What values do you put into the parameter object?

You’ll have no freaking clue without reading through the entire function. And even then, you might get it wrong.

Here’s the original signature:

Quick! What parameters does the function take?

If you were defusing a bomb and you had to answer that question or explode, and you only had a few seconds to go… I’m sure the one with separate parameters would be better.

OK, so the first best practice: Prefer separate named parameters for your function

Additionally, separate parameters also help if working in a functional programming style. One common thing in FP is to partially apply your functions, which is much harder to do if your function takes its parameters as an object.

While separate parameters are a good starting point, we run into trouble as soon as the function has optional parameters.

For functions with a single optional parameter, the solution is simple:

Best practice: optionals come last

However, if we have more than one optional parameter, the problem is… what if we only need to pass one optional parameter?

Ugh. Having to fill in values like undefined in there is just going to make it more complicated – both to call it, and to handle parameters in the function itself.

In cases with multiple optionals, we can just go back to objects. It doesn’t fully solve the clarity problem, but it means we don’t have to deal with passing extra values.

Best practice: Use an object for optional parameters if there’s more than one

Finally, if you’re using ES6 or TypeScript, we can make use of some of the new syntax.

For functions with optional parameters, it isn’t always clear the parameter is optional. With ES6, we can provide a default value to make it more obvious:

Best practice: Provide defaults for optional parameters

We can also use destructuring in the parameter list with objects, together with a default:

This gives you the best of both worlds. You can pass in parameters easily as an object, but the properties for the object can be easily seen from the function’s signature.

Best practice: Make use of ES6 destructuring where it makes sense

In addition to the suggestions above, using comment blocks before the function declaration is another useful habit to get into. It’s very useful for allowing the reader to get a quick summary not only about the function’s parameters, but also their expected types and any other considerations.

To sum it up:

There’s one more interesting trick you can do using ES6 default parameters. Normally, if you don’t pass a required parameter, nothing happens. But with default params, we can make the code automatically throw an error for missing required parameters! David Walsh has a great summary on that trick here.

Best practices for JavaScript function parameters