You order a pizza but don't pick a topping. The shop doesn't give you nothing. You get cheese, because that's the default. Pick pepperoni, and you get pepperoni instead. A default parameter is the cheese for your functions, a safe backup for when nobody chooses.
The problem: missing values become undefined
A parameter is the name for a value going into a function. If the caller doesn't pass anything, the parameter becomes undefined.
function greet(name) {
return "Hi, " + name;
}
console.log(greet()); // prints: Hi, undefined
That leads to weird bugs like the one above. Nothing crashes, so the problem can travel a long way before anyone notices the word undefined showing up on a page or in a message. A default fixes this right where the value comes in.
How to write a default
Put an equals sign and a value right after the parameter name.
function order(topping = "cheese") {
return topping + " pizza";
}
console.log(order()); // prints: cheese pizza
console.log(order("pepperoni")); // prints: pepperoni pizza
Call it with nothing, and it uses cheese. Pass pepperoni, and your value wins. Passing undefined on purpose counts as passing nothing, so order(undefined) also gives you a cheese pizza.
The default can be any expression, and it is worked out fresh on every call. So function addToy(toy, box = []) gives each call its own new empty array.
Why not use ||
Before defaults existed, people wrote v = v || 50. The || sign means or, so this says use v if it's truthy, otherwise use 50. That breaks with 0, because 0 is falsy.
function setVolumeOld(v) {
v = v || 50;
return v;
}
function setVolume(v = 50) {
return v;
}
console.log(setVolumeOld(0)); // prints: 50
console.log(setVolume(0)); // prints: 0
console.log(setVolume()); // prints: 50
console.log(setVolume(null)); // prints: null
You asked for 0 and got 50. A real default only kicks in when the value is undefined. Not 0, not an empty string, not even null. That makes it safer, and it also means passing null on purpose skips the default, as the last line shows.
The twist: a default can use an earlier parameter
function box(w, h = w) {
return w + " x " + h;
}
console.log(box(4)); // prints: 4 x 4
console.log(box(4, 2)); // prints: 4 x 2
Height equals width, so passing only the width gives you a square. Parameters are set up from left to right, which means a default can use any parameter before it, but not one that comes after it.
When to reach for a default
Give a parameter a default whenever a caller might reasonably leave it out. Settings are the classic case, like a volume, a size, a greeting or a number of retries. The default also works as a small piece of documentation. Anyone reading function order(topping = "cheese") can see what happens when they skip it.
If a value must always be given, a default can hide a mistake. In that case it's better to leave the default off, so the missing value shows up as a bug you can find.
Rule of thumb
If a value might be missing, give it a default.
Putting a parameter with a default before one without, like function order(size = "large", topping). To pick only the topping you'd have to pass undefined first. Put parameters with defaults at the end.
Check yourself
Defaults only kick in for undefined. 0 is a real value that was passed in, so the function keeps it.