Default and Rest Parameters in JavaScript

Introduction

Default parameters fill in missing values. Rest parameters (...rest) collect remaining arguments into a real array. Together they replace old arguments hacks and make APIs like console.log and Math.max patterns easy to write yourself.

Prerequisites

Default Parameter Values

javascript
// Defaults apply for undefined only
function createUser(name, role = "member", active = true) {
  return { name, role, active };
}
 
console.log(createUser("Ada"));
console.log(createUser("Lin", "admin"));

Defaults can use earlier parameters:

javascript
// Later default uses earlier param
function line(text, prefix = "[info]", message = `${prefix} ${text}`) {
  return message;
}
 
console.log(line("started"));

undefined vs Other Falsy Values

javascript
// null does NOT trigger default (only undefined)
function pad(value = 0) {
  return value;
}
 
console.log(pad());
console.log(pad(null));
console.log(pad(0));

Rest Parameters

javascript
// Collect all arguments after first two
function sum(first, second, ...rest) {
  let total = first + second;
  for (const n of rest) {
    total += n;
  }
  return total;
}
 
console.log(sum(1, 2, 3, 4, 5));

Rest must be the last parameter in the list.

Spread at Call Site

javascript
// Spread array into arguments
const nums = [3, 1, 4, 1, 5];
console.log(Math.max(...nums));

Opposite of rest: rest gathers in definition; spread expands at call.

Combining Defaults and Rest

javascript
// Flexible logger
function log(level = "info", ...messages) {
  messages.forEach((msg) => {
    console.log(`[${level}]`, msg);
  });
}
 
log();
log("warn", "disk full", "retry soon");

Mini Example: createRange Helper

javascript
// start, end, step with defaults
function createRange(start = 0, end = 10, step = 1) {
  const result = [];
  if (step === 0) return result;
  if (step > 0) {
    for (let i = start; i < end; i += step) result.push(i);
  } else {
    for (let i = start; i > end; i += step) result.push(i);
  }
  return result;
}
 
console.log(createRange());
console.log(createRange(2, 8, 2));

FAQ

Rest vs spread—same operator?

Same ... syntax, different positions: rest in parameter list, spread in call/array literal.

Can I default a destructured parameter?

Yes: function f({ x = 1, y = 2 } = {}) { }—common in React props patterns.

Does rest include all arguments?

Only those after fixed parameters—function f(...all) collects everything.

What comes next?

this and arrow functions.