In ECMAScript 6, you can use destructuring, which looks like this:
function selectEntries({ start=0, end=-1, step=1 }) {
···
}
If you call selectEntries() with zero arguments, the destructuring fails, because you can’t match an object pattern against undefined. That can be fixed via a default value. In the following code, the object pattern is matched against {} if the first parameter is missing.
function selectEntries({ start=0, end=-1, step=1 } = {}) {
···
}
You can also combine positional parameters with named parameters. It is customary for the latter to come last:
someFunc(posArg1, { namedArg1: 7, namedArg2: true });
In principle, JavaScript engines could optimize this pattern so that no intermediate object is created, because both the object literals at the call sites and the object patterns in the function definitions are static.
Thus making it possible to have functions with default parameters that can be optionally called when the function executes.