brianmearns
brianmearns

Reputation: 9967

Idiomatic way to make middle arguments optional

What is a common way to implement a JavaScript function whose middle argument(s) are optional, but the last argument is required? An idiomatic ES2015 solution is preferred.

E.g., I commonly see functions that can be invoked in multiple ways, like this:

func(firstArg, callback);
func(firstArg, options, callback);

So what actually happens is that the number of arguments affects the interpretation of each argument.

I know I can handle this by checking the length of the arguments, something like this:

//     func(firstArg, options, callback);
// or: func(firstArg, callback);
function (firstArg, ...args) {
    let options = {};
    if (args.length > 1) {
        options = args.shift();
    }
    let callback = args[0];
    // And do stuff ...
}

But it seems clunky. Is there a better way to do this?

Upvotes: 5

Views: 2450

Answers (2)

Andy
Andy

Reputation: 63524

Use ...args and pop() the callback from the array:

function thing(...args) {
  var cb = args.pop();
  //... args is now [1, obj]
  cb(args[0]);
}

thing(1, { a: 1 }, function (data) {
  console.log(data); // 1
});

Upvotes: 2

a better oliver
a better oliver

Reputation: 26828

An idiomatic way would involve type checking. You can also leverage default parameters.

function test(firstArg, callback, options = {}) {
  if (typeof options == 'function') {
    callback = arguments[2];
    options = arguments[1];
  }

}

This not only ensures that you always have an options object but also works if someone switches the arguments for callback and options. So it doesn't matter if the options come in second or last. Moreover and maybe more importantly the source code clearly tells us its intention.

Upvotes: 0

Related Questions