Default Parameters

Fallback values for missing arguments. No more undefined checks.

Basics

Assign default values directly in the parameter list.

// Old way — manual checks:
function greet(name) {
  name = name || "World"; // ⚠️ buggy with falsy values
  return "Hello, " + name + "!";
}

// ES6 — default parameters:
function greet(name = "World") {
  return `Hello, ${name}!`;
}

greet("Alice"); // "Hello, Alice!"
greet();        // "Hello, World!"
greet(undefined); // "Hello, World!" (undefined triggers default)

// Multiple defaults:
function createUser(name = "Anonymous", role = "viewer", active = true) {
  return { name, role, active };
}

createUser();              // { name: "Anonymous", role: "viewer", active: true }
createUser("Alice");       // { name: "Alice", role: "viewer", active: true }
createUser("Bob", "admin"); // { name: "Bob", role: "admin", active: true }

Expressions as Defaults

Defaults can be any expression — they're evaluated at call time.

// Function calls as defaults:
function getTimestamp() {
  return Date.now();
}

function log(message, time = getTimestamp()) {
  console.log(`[${time}] ${message}`);
}

log("start"); // [1717593600000] start
log("end");   // [1717593601000] end  ← different time!

// Default is evaluated fresh each call, not once at definition

Default expressions are lazily evaluated — they run every time the function is called without that argument.

1 / 2

Gotchas

Edge cases to watch for.

// null does NOT trigger default (only undefined does):
function test(x = 42) { return x; }
test(undefined); // 42 (default used)
test(null);      // null (NOT the default!)
test(0);         // 0 (NOT the default!)
test("");        // "" (NOT the default!)
test(false);     // false (NOT the default!)

// Only missing or explicitly undefined → default

// arguments object doesn't reflect defaults:
function show(a = 1, b = 2) {
  console.log(arguments.length); // actual args passed
}
show();     // arguments.length = 0 (not 2!)
show(10);   // arguments.length = 1

// Default params create their own scope (rare edge case):
let x = 1;
function f(a = x, b = () => a) {
  let x = 2;  // doesn't affect default 'a'
  return b(); // returns the parameter 'a', not local 'x'
}
f(); // 1

Patterns

Useful patterns with default parameters.

// 1. Required parameter (throw on missing):
function required(name) {
  throw new Error(`Missing required param: ${name}`);
}

function createUser(name = required("name"), email = required("email")) {
  return { name, email };
}
createUser(); // Error: Missing required param: name

// 2. Options object with defaults:
function fetchData(url, {
  method = "GET",
  headers = {},
  timeout = 5000,
  retry = 3,
} = {}) {
  // All options have defaults, and the whole object defaults to {}
  return { url, method, headers, timeout, retry };
}
fetchData("/api/users"); // all defaults applied
fetchData("/api", { method: "POST", timeout: 10000 });

// 3. Factory with configurable defaults:
function createLogger(prefix = "APP", level = "info") {
  return (message) => console.log(`[${prefix}:${level}] ${message}`);
}
const log = createLogger("AUTH", "debug");
log("User logged in"); // [AUTH:debug] User logged in

FAQ

Common questions about default parameters.