0

Coming from Python, I'm used to defining default params like this:

def someFunc(defarg1=0, defarg2=10, defarg3="Hello", defarg4=100):

Then I can use it like so:

someFunc(defarg3="Goodbye")

In Javascript, I understand you can do the same in the definition:

someFunc(defarg1=0, defarg2=10, defarg3="Hello", defarg4=100) {}

But when I want to call the function and only change, say, defarg3, I can't do that since each argument is converted to positional arguments and their names are ditched. So doing this in Javascript doesn't work:

someFunc(defarg3="Goodbye");

From what I understand, I need to pass every other argument before defarg3. And since I don't want to change the default args before it, I have to supply the same default value:

someFunc(0, 10, "Goodbye");

Perhaps I'm missing something, but this seems incredibly redundant and prone to making mistakes. What if a function has a whole lot of default args and I just want to change one. There has to be a way instead of redundantly supplying the same default argument for previous args every time.

VagrantC
  • 687
  • 2
  • 13
  • 31
  • 2
    It's not a pretty solution, but you could pass `undefined` into the argument positions where you want to use the defaults – Jon Warren Oct 21 '20 at 20:04
  • You are pretty much correct, there is no real way around this in JavaScript. – Glen Carpenter Oct 21 '20 at 20:05
  • @GlenCarpenter, not true there is a solution, don't use traditional arguments, use an object `{}` instead. That allows for unlimited data to be passed. – imvain2 Oct 21 '20 at 20:08
  • @imvain2 While that would work as a workaround, I'm not sure if that's a solution for this specific question. What if you don't want to / are not able to change the function definition for which you're passing in the arguments? – Jon Warren Oct 21 '20 at 20:10
  • @imvain2 that is an interesting workaround, wouldn't have thought of it! – Glen Carpenter Oct 21 '20 at 20:13
  • See [also](https://stackoverflow.com/questions/894860/set-a-default-parameter-value-for-a-javascript-function). – Ben Aston Oct 21 '20 at 21:11

4 Answers4

2

If you can author the parameters then use a destructuring assignment with default properties. This enables you pass an object with only the parameters that you need to pass without having to respect the position of the argument.

function example({ a = true, b = false, c = 1 } = {}) {
  console.log(a, b, c);
}

example({ b: true });
example({ a: false });
example({ c: 0, a: false, b: true });
example();
Emiel Zuurbier
  • 19,095
  • 3
  • 17
  • 32
  • Didn't think to use objects. This really seems like the best workaround that at least satisfies what I'm trying to do. – VagrantC Oct 21 '20 at 20:24
1

What I prefer to do is pass an "object" instead of using arguments. Then you can access a parameter within the function like args.parameter.

You can also have a default set of data then just "merge" both together.

function test(p){
  d = {
    "default" : 3
  }
  
  args = Object.assign(d, p);
  
  console.log(args);
}

test({
  "test" : 1
});

test({
  "test2" : 1
});
imvain2
  • 15,480
  • 1
  • 16
  • 21
0

If you want to avoid a positional parameter list, use an object, destructuring assignment, and default values:

function someFunc({ defarg1=1, defarg2=2, defarg3=3, defarg4=4 }) {
  console.log(defarg1, defarg2, defarg3, defarg4)
}

someFunc({ defarg2: 'bananas' }) // 1 bananas 3 4
someFunc({ defarg2: null })      // 1 null 3 4
someFunc({ defarg2: undefined }) // 1 2 3 4
someFunc({})                     // 1 2 3 4
someFunc()                       // Uncaught TypeError: Cannot read property 'defarg1' of undefined
someFunc(undefined)              // Uncaught TypeError: Cannot read property 'defarg1' of undefined
someFunc(null)                   // Uncaught TypeError: Cannot read property 'defarg1' of null

Note:

  • default values are used when the property is not specified, or its value is undefined. This will suit most use cases.
  • an object must be supplied as an argument for this pattern to work

If you want to permit the user to supply nothing at all to the function then you must supply a default value for the outer object parameter too.

Note that if null is supplied as an argument, the default value is not triggered.

function someFunc({ defarg1=1, defarg2=2, defarg3=3, defarg4=4 } = {}) {
  console.log(defarg1, defarg2, defarg3, defarg4)
}

someFunc({ defarg2: 'bananas' }) // 1 bananas 3 4
someFunc({ defarg2: null })      // 1 null 3 4
someFunc({ defarg2: undefined }) // 1 2 3 4
someFunc({})                     // 1 2 3 4
someFunc()                       // 1 2 3 4
someFunc(undefined)              // 1 2 3 4
someFunc(null)                   // Uncaught TypeError: Cannot read property 'defarg1' of null

Finally, if you invoke the function with Function#apply, you can avoid using object destructuring and make use of the fact that arrays support elision:

function someFunc(defarg1=1, defarg2=2, defarg3=3, defarg4=4) {
  console.log(defarg1, defarg2, defarg3, defarg4)
}
someFunc.apply(null, [,'bananas']) // 1 bananas 3 4
Ben Aston
  • 53,718
  • 65
  • 205
  • 331
0

You can do something like this, see rest parameter javascript

function somefunc(...args) {
 // args is an Array
 console.log(args);
}
Mahmud
  • 41
  • 3