3

I'm spinning my head around this for a little while, but it seems I can't manage to make this work the way I would like it to. Actually, all I want here is to have nested default values for an optional argument. The output I'd like to see should be:

55, 44, { sub1: '0', sub2: 55, sub3: 'all'}

Instead, I just get this:

55, 44, { sub2: 55 }

Could somebody give me a heads up on this one?

function foo({ param1=55, param2=44, param3:param3 = { sub1:sub1='0', sub2:sub2=200, sub3:sub3='all' } } = { }) {
  console.log(param1, param2, param3);
}

foo({
  param3: {
    sub2: 55
  }
});
2
  • 2
    Doesn't the default value only get applied if nothing is passed into that parameter? I'm pretty sure it doesn't run something like Object.assign Commented Aug 29, 2017 at 21:41
  • If you just skip param3 the whole default object gets into play. I honestly don't know if you even can go for nested default values like this, can't find much about it. Commented Aug 29, 2017 at 21:43

2 Answers 2

6

You are passing {sub2: 55} for param3, so it will not evaluate the default value { sub1:sub1='0', sub2:sub2=200, sub3:sub3='all' } (which is a literal here, not an assignment target, so wouldn't do what you think it does anyway).

If you want param3 to always be an object with 3 properties, constructed from the three default-valued variables, you have to build it explicitly yourself:

function foo({param1=55, param2=44, param3: {sub1='0', sub2=200, sub3='all'} = {}} = {}) {
  var param3 = {sub1, sub2, sub3};
  console.log(param1, param2, param3);
}
Sign up to request clarification or add additional context in comments.

4 Comments

In other words, there is no way to create default values for nested destructured arguments?
@jAndy Not sure what you mean. You can nest argument destructuring arbitrarily, and put default values on every level. What you cannot do is have destructuring mutate arguments or create new objects whose parts are made from defaulted values.
So, if you pass param3 in this example, it will always overwrite the entire object right? The point I'm wondering is, if you can again create default values within that passed object (it's basically the same thing as on the outside, just nested). But it seems you already gave the answer to that question. I'd like to have that feature anyways.
@jAndy Yes, if there is a value it gets assigned to the target and the default initialiser is not evaluated. Whether the target is another destructuring, or a variable, does not matter. See here for more explanation.
0

Default parameters only get assigned if the parameter is empty. I think you need to use Object.assign in the body of the function:

const defaults = { sub1:sub1='0', sub2:sub2=200, sub3:sub3='all' }
function foo({ param1=55, param2=44, param3 } = { }) {
  const myParam3 = Object.assign({}, defaults, param3);
  console.log(param1, param2, myParam3);
}

foo({
  param3: {
    sub2: 55
  }
});

1 Comment

You don't need param3:param3 = defaults, just param3 would be enough. Then you can also inline the defaults in the Object.assign call, and merge it with the first object literal.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.