Consider the following JavaScript function call:


As you can see, we’re passing an argument of true. That’s a primitive type, and as such, it’s not clear what it’s doing. Now imagine if the referenced function were rewritten to take an object parameter instead. Calling it would then look something like this:

fetchUser({ forceReload: true });

This is much more clear. We can reasonably deduce that by passing true, we’re telling the code to ignore local cache and do a hard HTTP call to a server.

As a general rule, named parameters are better than simple boolean parameters. I’ve gotten to where I hardly ever write function definitions that have simple primitives as parameters, even if the function only has one parameter. Never underestimate the value of code readability.

A second reason why primitive parameters are bad is this: they make future extensibility harder. When it does come time to add a second parameter, you have to worry about changing the order of them. If you’re working with a team, you’ll soon be debating which parameters should come first. A lot of drama and intricacy can surround this. Usually developers want the most important parameters to go first. Once they’ve agreed on the order of importance, there’s still the debate about which parameters should have default values and which ones should be required. It especially gets messy if some of the more important parameters have logical defaults while some of the less important ones don’t. Once everyone’s finally agreed on how it should work in an ideal world, then there’s the debate about whether it’s worth refactoring every place that calls this method. Should you refactor, or just tack on the new parameter at the end with a default value as a less-than-ideal solution to avoid “busywork”? Remember, Chris has an unrelated work-in-progress branch that is touching this code a lot already, and he’d have to deal with a bunch of conflicts if the function signature were to get changed upstream. He’s ok with the change, but can it wait a couple weeks until his thing is done? There are so many opportunities for confusion and disagreement and frustration and subtle procrastination in all of this.

This whole debacle dissipates by simply using an object as your parameter. With named parameters, order doesn’t matter, because object properties are ordered alphabetically. And the best part? Thanks to object destructuring, you don’t even have to change the body of your function. If your function definition used to look like this:

const fetchUser = (forceReload = false) => {
  // function body that references `forceReload` boolean

It can now look like this:

const fetchUser = ({ forceReload = false }) => {
  // body remains unchanged

Never did an opening and closing bracket solve so many problems so effortlessly.