17

What is the best way to create a function that takes optional arguments in nodejs?

for example I know this method:-

    function optionalArguments(a,b){
        var a = a || "nothing";
        var b = b || "nothing";
    } 

but in this case if I do this :

optionalArguments(false,false)

both a and b return "nothing" although I have passed an argument.

and also I get unexpected token error when I call the function like this :

optionalArguments(,"xxx");

Is there a better or a standard method to tackle optional arguments in nodejs?

Any help is appreciated. Thanks in advance.

4 Answers 4

39

If you are using Node.js v6 (or higher), you have access to default parameters.

function optionalArguments(a="nothing", b="nothing") {
  return `a: ${a}, b: ${b}`;
}

Then

optionalArguments(false, false)     // 'a: false, b: false'
optionalArguments('this')           // 'a: this, b: nothing'
optionalArguments()                 // 'a: nothing, b: nothing'
optionalArguments(undefined,'that') // 'a: nothing, b: that'
Sign up to request clarification or add additional context in comments.

Comments

17

You do that exactly like for client side javascript.

The way you suggest does work but is, as you noticed, painful when the arguments that can be omitted aren't the last ones.

In that case, what's commonly used is an "options" object :

function optionalArguments(options){
    var a = options.a || "nothing";
    var b = options.b || "nothing";
}

Note that || is dangerous. If you want to be able to set arguments like false, "", 0, NaN, null, you have to do it like this :

function optionalArguments(options){
    var a = options.a !== undefined ? options.a : "nothing";
    var b = options.b !== undefined ? options.b : "nothing";
}

A utility function can be handy if you do this a lot :

function opt(options, name, default){
     return options && options[name]!==undefined ? options[name] : default;
}

function optionalArguments(options){
    var a = opt(options, 'a', "nothing");
    var b = opt(options, 'b', "nothing");
}

This way you can even call your function with

optionalArguments();

4 Comments

but when I pass options.a=false I still get "nothing" although the value should have been false is there a way to tackle this?
Object deconstruction can become very useful in this case. The function definition can be rewritten as function optionalArguments({a, b}) { /* use a and b like normal parameters*/ } optionalArguments({a: 'foo', b: 42});. Couldn't find a lot of official information about it though: wiki.ecmascript.org/doku.php?id=harmony:destructuring
@dystroy I am sure you meant options[name]
Thanks for the function pageOptions, i was wondering how to use it.
2

The || is just the regular old or operator. It comes in handy when the value is expected to not be falsey. But, if values like 0, false, or null are valid and expected, you need to take a different approach.

== null

To check to see if a non-null value was passed, use == null. This will return true when null or undefined are passed in:

function optionalArguments (a, b) {
    a = a == null ? "nothing" : a;
    b = b == null ? "nothing" : b;
    ...
}

In most cases, this is the best approach for implementing optional parameters. It allows the caller to pass null when the default value is desired. It's particularly useful when a caller wants to pass a value for the second argument, but use the default for the first. Eg, optionalArguments(null, 22)

=== undefined

If null is a valid and expected value, compare as above using undefined and the === operator. Make sure that you are using a valid value of undefined for your comparison. It is possible for a script to say var undefined = 0, causing endless headaches for you. You can always do === void 0 to test for undefined.

arguments.length

What if I call your function like this?

optionalArguments("something", void 0);

In this case, I did pass a value, but that value is undefined. There may be times when you truly want to detect whether an argument was passed in or not. In this case, you need to check the arguments.length:

function optionalArguments (a, b) {
    a = arguments.length > 0 ? a : "nothing";
    b = arguments.length > 1 ? b : "nothing";
    ...
}

2 Comments

Did you really see a case where it was useful to detect if the caller passed undefined as last argument rather than passing nothing ? I'd say this was an utterly wrong design...
I don't remember the details, but I do remember a time once when I wanted to see if an argument was passed, even if it was undefined. I agree, it's not a great design.
0

As an easy way to use default arguments and still be able to use the false value, you can do like this

function optionalArguments(a, b){
  a = typeof a !== 'undefined' ? a : "nothing"; 
  b = typeof b !== 'undefined' ? b : "nothing";
} 

See also alternative options on this question

Whichever option you chose, optionalArguments(, "xxx") will not be valid because the missing parameter makes the syntax invalid: the code cannot be parsed. To fix it, you can use

optionalArguments(undefined, "xxx");

3 Comments

The var is unnecessary here. And if you use a != null ? ..., then you can also use null instead of undefined to omit the argument: optionalArguments(null, "xxx"); (less to type ;) (only of course if null is not a valid value)).
@FelixKling Thanks, I removed the extra var in my anwser. About using null instead of undefined, I think undefined is more adapted to describe a missing value, but I guess that's subject to opinion!
I agree! As I said, it depends on the actual use case.

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.