Functions used to start with three lines of checking: if this argument is missing, use that value. Those lines added nothing and hid the real work.
Default parameters move that information where it is useful: into the signature, visible on first reading and to tooling.
Definition
A default parameter is a value written after an equals sign in the parameter list. It is used when the matching argument is missing or explicitly holds undefined.
function greet(name = "visitor", punctuation = "!") {
return "Hello " + name + punctuation;
}
console.log(greet()); // Hello visitor!
console.log(greet("Ada")); // Hello Ada!
console.log(greet(undefined, "...")); // Hello visitor...
console.log(greet(null)); // Hello null!The last line is the one to remember: null is a value, so the default does not apply.
What triggers the default, and what does not
This two-column table settles the doubt once and for all.
| Argument passed | Default applies |
|---|---|
| None | Yes |
undefined | Yes |
null | No |
0, "", false | No |
That is exactly the behavior of Nullish coalescing (??) restricted to undefined, and not that of a || which would also overwrite falsy values. See Truthy and falsy.
Two behaviors that come in handy
A default is evaluated on every call, and it can build on the parameters declared before it.
function buildLink(base, path = "/", url = base + path) {
return url;
}
console.log(buildLink("https://believemy.com")); // https://believemy.com/
console.log(buildLink("https://believemy.com", "/en")); // https://believemy.com/en
function add(item, cart = []) {
cart.push(item);
return cart;
}
console.log(add("keyboard").length); // 1
console.log(add("mouse").length); // 1, a fresh array on every callThat second point avoids a well-known trap from other languages, where a default array is created once and fills up from one call to the next. In JavaScript, every call receives a fresh value.
Frequently asked questions
Can a destructured object have defaults?
Yes, and it is the most comfortable pattern for a function taking options. Writing function config({ theme = "light" } = {}) gives every field a default, and the trailing = {} lets the function be called with no argument at all. See Destructuring for the full syntax.
Can a default parameter be a function call?
Yes, any expression works, a function call included. It is only evaluated when the argument is missing, which avoids useless work in the common case. Be careful not to hide a Side effect in there, though: a signature is not where anyone expects to find one.
Should parameters with defaults come last?
Strongly recommended. A default placed before a required parameter forces the caller to write undefined to skip it, which reads terribly. Order parameters from the most required to the most optional, or gather the options into a single object.