JS Tip of the Day: Default Parameters with Destructuring

Default Parameters with Destructuring
Version: ES2015
Level: Intermediate

When destructuring, you can specify default values for those that may not exist within the destructured object.

let {one, two, three = 3} = { one: 1, two: 2 };
console.log(one, two, three); // 1 2 3

Defaults can also be used in function parameters.

function countToThree(one, two, three = 3) {
    console.log(one, two, three);
}
countToThree(1, 2); // 1 2 3

And parameters can be destructured.

function countToThreeIn({ one, two, three }) {
    console.log(one, two, three);
}
let values = { one: 1, two: 2 };
countToThreeIn(values); // 1 2 undefined

And destructured values in parameters can have defaults.

function countToThreeIn({ one, two, three = 3 }) {
    console.log(one, two, three);
}
let values = { one: 1, two: 2 };
countToThreeIn(values); // 1 2 3

And parameters as a whole, even when destructuring, can have defaults!

let values = { one: 1, two: 2 };
function countToThreeIn({ one, two, three = 3 } = values) {
    console.log(one, two, three);
}
countToThreeIn(); // 1 2 3

One thing to bear in mind, is that when a default is supplied to a parameter, even if destructured, that default will only apply if the argument for that parameter is not specified or undefined. The default would not get applied to the destructuring otherwise. If an argument is supplied, its up to the defaults within the destructuring to provide default values.

let values = { one: 1, two: 2 };
function countToThreeIn({ one, two, three = 3 } = values) {
    console.log(one, two, three);
}
countToThreeIn(); // 1 2 3
countToThreeIn({}); // undefined undefined 3

For this reason, parameter defaults for destructured parameters are usually defined as empty objects with defaults handled in the destructuring. This way, no argument means an empty object for the parameter which in turn means using all of the defaults in the destructuring.

function countToThreeIn({ one = 1, two = 2, three = 3 } = {}) {
    console.log(one, two, three);
}
countToThreeIn(); // 1 2 3
countToThreeIn({}); // 1 2 3
countToThreeIn({ two: 'two' }); // 1 two 3

More info: