Maintainable Options Parameters for Functions in JavaScript

dave.js
Quick Code
Published in
4 min readMay 15, 2018

--

My friend/co-worker Sam Jesso told me that he hates using flags to modify the behaviour of functions. It makes sense. Functions should follow the single responsibility principle and do exactly one thing. It makes testing and maintaining code easier because it keeps functions simple and concise. However, diving into almost any codebase will reveal that we often make exceptions and use flags.

Whether or not these exceptions are justified is not what I want to discuss. It would be impossible to come up with a set of rules or guidelines for when an exception makes sense because everybody’s code is different. But if you’ve already decided that you want to pass flags into your function, there is a simple trick you can use to make your functions’ interfaces more developer-friendly.

Rather than treating flags (or options) as separate parameters, we can group them into a single options object:

A function refactored to group flags into an options object.

Grouping options into a single object has several advantages over using separate parameters. To better understand these advantages, let’s take a look at a less abstract example…

An Example with Formatting Time

Here’s a simple function to get a formatted time string from a Date object:

A simple function that takes in a Date object and returns a formatted time string.

Side note: Yes, I wrote my own version of leftPad because I’m not pulling in simple dependencies for a blog post. (Also if you don’t cringe when you hear talk of leftPad, take a moment to read this.)

A function that fills empty positions to the left of a number with zeros. (Yes, I know how error-prone this is but it works for our implementation here.)

Anyway, back to the example.

New Requirements

We have a function for formatting time and it does a great job. But now we want to have the option switch between 12-hour and 24-hour time. And we also want to exclude seconds in some cases.

No problem, we can just add some extra parameters to the function:

A function that takes in a Date object and returns a formatted time string in either 12-hour or 24-hour time, and with seconds optionally hidden.

There are several issues with this approach:

  • The parameters must be passed in a specific order. If we want to hide seconds, we must still pass a value for is12Hours before we can specify one for showSeconds.
  • The parameters are unnamed. If the function is being called far away from the definition, it may not be clear what the parameters mean. We must go to the function definition to find out what the various true/ false values do.

These issues make the function interface very difficult to read understand and they amplify the potential for human error especially when a function has many options because it’s easy to accidentally skip a parameter or mix up their order.

Refactoring with an options object

A simple way to fix these issues is to refactor the function to use an object for flags/options:

This approach solves the issues that exist with passing flags as separate parameters by:

  • Exposing the flag names to the interface.
  • Forcing developers to label the flags properly.
  • Making the ordering of flags irrelevant.
  • Allowing exclusion of flags when we want the default behaviour.

In addition to making the function more readable we’ve also made it maintainable because it’s now easier to add many flags to our formatTime function without adding more and more nameless booleans, making the function calls unreadable. We could add flags for showMinutes, showMilliseconds, or even an option to specify a custom delimiter to replace the default colon. Whatever flags or options we add, the function will remain relatively readable.

One More Thing…

Even though we’ve made the function’s interface easy to use and add to doesn’t mean that all the functionality for those parameters should be aggregated into a single function. Use your best judgement and decide when to delegate functionality to helper functions.

--

--

dave.js
Quick Code

I’m an artsy software engineer. I write about JavaScript/React, and sometimes my opinions about other things. ¯\_(ツ)_/¯