← Back to all tutorials

Default Parameters

Set default values for function parameters — cleaner code, no more manual undefined checks.

Default Parameters

ES6 lets you set default values directly in the function signature. No more manual undefined checks or || fallbacks.

The Old Way (ES5)

function greet(name) {
    name = name || "World";  // Fallback if name is undefined
    return "Hello, " + name + "!";
}

greet();        // "Hello, World!"
greet("Alice"); // "Hello, Alice!"

// Problem: '' (empty string) and 0 are falsy!
greet("");   // "Hello, World!" ← Bug! Empty string is valid
greet(0);    // "Hello, World!" ← Bug! 0 is valid

The ES6 Way

function greet(name = "World") {
    return `Hello, ${name}!`;
}

greet();         // "Hello, World!"
greet("Alice");  // "Hello, Alice!"
greet("");       // "Hello, !"  ← Correctly uses empty string
greet(0);        // "Hello, 0!" ← Correctly uses 0

Defaults only activate when the argument is undefined (or not passed at all).

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 }
createUser("Carol", "editor", false); // { name: "Carol", role: "editor", active: false }

Defaults Can Use Previous Parameters

function createPrice(amount, tax = amount * 0.1) {
    return { amount, tax, total: amount + tax };
}

createPrice(100);       // { amount: 100, tax: 10, total: 110 }
createPrice(100, 15);   // { amount: 100, tax: 15, total: 115 }

The tax default references amount — parameters are evaluated left-to-right.

Defaults Can Be Expressions

function getTimestamp(date = new Date()) {
    return date.toISOString();
}

// Called without argument: uses current date/time
getTimestamp();  // "2026-03-12T16:30:00.000Z"

// Called with a specific date
getTimestamp(new Date("2025-01-01"));  // "2025-01-01T00:00:00.000Z"

The default expression is evaluated at call time, not at definition time. Each call to getTimestamp() gets a fresh new Date().

Defaults Can Be Function Calls

function generateId() {
    return Math.random().toString(36).substr(2, 9);
}

function createItem(name, id = generateId()) {
    return { name, id };
}

createItem("Widget");  // { name: "Widget", id: "k8f3m2x9q" }
createItem("Gadget");  // { name: "Gadget", id: "p2r7n4b1w" }  ← different ID

Skipping a Parameter

function setup(width = 800, height = 600, title = "Untitled") {
    return { width, height, title };
}

// To skip 'width' and use default, pass undefined:
setup(undefined, 400, "My App");
// { width: 800, height: 400, title: "My App" }

// Note: null does NOT trigger the default
setup(null, 400);
// { width: null, height: 400, title: "Untitled" }

Defaults with Destructuring

function configure({ host = "localhost", port = 3000, debug = false } = {}) {
    console.log(`Server: ${host}:${port}, debug: ${debug}`);
}

configure();                           // "Server: localhost:3000, debug: false"
configure({ port: 8080 });             // "Server: localhost:8080, debug: false"
configure({ host: "0.0.0.0", debug: true }); // "Server: 0.0.0.0:3000, debug: true"

The = {} at the end is a default for the entire parameter object — without it, calling configure() with no arguments would throw an error.

Key Takeaways

  • Default parameters provide fallback values directly in the function signature
  • Defaults trigger only on undefined, not on null, 0, or ""
  • Later parameters can reference earlier ones
  • Default expressions are evaluated at call time, not definition time
  • Pass undefined explicitly to skip a parameter and use its default
  • Combine with destructuring for powerful configuration objects