The way to check for parameters depends on what type of information you’re passing to the function, and how you want your function to handle edge cases.
In most cases, you can use:
...
bar = bar || ...default value here...
...
However, it might be an issue when you want to pass in falsey values (false
, 0
, NaN
, ''
, undefined
, null
):
function foo(bar) {
bar = bar || 5
console.log(bar)
}
foo() // 5
foo(undefined) // 5
foo(null) // 5
foo(1) // 1
foo(0) // 5, probably not what you wanted
Instead, you can check against undefined
:
...
if (bar == undefined) {
bar = 5
}
...
…however using the loose check allows both null
and undefined
to be overwritten (null == undefined
):
function foo(bar) {
if (bar == undefined) {
bar = 5
}
console.log(bar)
}
foo() // 5
foo(undefined) // 5
foo(null) // 5
foo(1) // 1
So instead, a strict equality comparison (===
) is generally preferred (null !== undefined
):
function foo(bar) {
if (bar === undefined) {
bar = 5
}
console.log(bar)
}
foo() // 5
foo(undefined) // 5
foo(null) // null
foo(1) // 1
ES2015 introduced default parameters, which are essentially equivalent to strict checking against undefined
:
function foo(bar = 5) {
console.log(bar)
}
foo() // 5
foo(undefined) // 5
foo(null) // null
foo(1) // 1
This could lead to trouble if you need to know whether undefined
was passed as a parameter.
If you want to be absolutely certain that you’re not passing up an argument that was provided, you can check the number of arguments passed to the function:
...
if (arguments.length < 1) {
bar = 5
}
...
Which means that you can successfully pass undefined
as an argument while also choosing to use a different default:
function foo(bar) {
if (arguments.length < 1) {
bar = 5
}
console.log(bar)
}
foo() // 5
foo(undefined) // undefined
foo(null) // null
foo(1) // 1
If you have multiple parameters, you may want to use multiple defaults. I’ve recently found a use case for fallthrough on a switch statement, although the utility is questionable:
function foo(bar, baz, fizz, buzz) {
switch (arguments.length) {
case 0:
bar = 1;
//continue; might as well point out that implicit fall-through is desired
case 1:
baz = 2;
//continue;
case 2:
fizz = 3;
//continue;
case 3:
buzz = 4;
//continue;
}
console.log(bar, baz, fizz, buzz)
}
foo() // 1 2 3 4
foo(10) // 10 2 3 4
foo(10, 20) // 10 20 3 4
foo(10, 20, 30) // 10 20 30 4
foo(10, 20, 30, 40) // 10 20 30 40