2

I have this function:

const func = (a, b, options = { opt1: false, opt2: false, opt3: false }) => {
 // do something
 console.log(options); // { opt1: false, opt2: false, opt3: false }
}

so when I call it without any params, I'm getting this

func('a', 'b', { opt3: true });
// { opt3: true }

instead of expected:

// { opt1: false, opt2: false, opt3: true }
2
  • But you are calling it with { opt3: true } as the third parameter(func(a, b, { opt3: true })).
    – TheMaster
    Commented Sep 8, 2019 at 16:40
  • Default parameters for an object don't merge individual properties. You get the whole object passed or the whole default object if nothing passed.
    – jfriend00
    Commented Sep 8, 2019 at 16:43

3 Answers 3

4

You've defaulted options, but you haven't defaulted the various properties within options. Since you're supplying an object for options, that object is being used.

You could use destructuring to supply defaults for the properties, and then supply a blank default for the parameter:

const func = (a, b, { opt1 = false, opt2 = false, opt3 = false } = {}) => {
 // do something
 console.log(opt1, opt2, opt3);
};

func(1, 2, {opt1: true});
func(1, 2);

Of course, you end up with the options as discrete variables rather than as an object. You can always reconstitute the object:

const func = (a, b, { opt1 = false, opt2 = false, opt3 = false } = {}) => {
 const options = {opt1, opt2, opt3};
 // do something
 console.log(options);
};

func(1, 2, {opt1: true});
func(1, 2);

And of course, since that's your own object, you can happily assign other properties to it if you like without worrying about modifying the caller's object.

If you don't want to use destructuring, you just supply the defaults separately like we used to before ES2015, but perhaps with property spread rather than Object.assign:

const func = (a, b, options = {}) => {
 // do something
 options = {opt1: false, opt2: false, opt3: false, ...options };
 console.log(options);
};

func(1, 2, {opt1: true});
func(1, 2);

0

This is expected behavior. When you create your default options parameter, the default value is has 3 fields. When you pass your {opt3: true}, you are skipping the default since you are providing your own. The default does not fill in your missing values for you.

1
  • Sorry I'm not native speaker and sometimes it's hard for me to formulate what is my issue, I understand it's working as intended, but I just wonder if there work around which won't require bunch lines of repeated code.
    – sloppy
    Commented Sep 8, 2019 at 16:44
0

It's a correct behavior. options = { opt1: false, opt2: false, opt3: false } only if there is no object provided when you call your function.

const func = (a, b, options = { opt1: false, opt2: false, opt3: false }) => {
  // do something
  options.opt1 = options.opt1 || false
  options.opt2 = options.opt2 || false
  options.opt3 = options.opt3 || false

  console.log(options); 
 }

This is how you can do it by checking object properties and setting them based on if they were set or not.

1
  • yes, I understand, what I want to know is there work around?
    – sloppy
    Commented Sep 8, 2019 at 16:42

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.