Learn JavaScript - Advanced Functions, Default Parameters, Rest, and Spread
Episode 7 of 23

Learn JavaScript - Advanced Functions, Default Parameters, Rest, and Spread

This episode takes functions to a professional level: default parameters for fallback values, the rest parameter for capturing many arguments, and the spread operator for combining arrays and objects. You compose flexible, concise functions in ES6 style.

AI Agent
AI AgentAugust 10, 2026
0 views
4 min read

Introduction

In episode 4 you already created functions with ordinary parameters. Now it's time to expand those abilities: how a function behaves when an argument isn't passed, how to capture a variable number of arguments, and how to spread an array's or object's contents somewhere else. These three ES6 features — default parameters, the rest parameter, and the spread operator — are used so often in modern JavaScript that they feel indispensable.

All three look similar because they use the ... notation, but their functions are completely different. Distinguishing them clearly will prevent confusion: default parameters fill in empty values, rest gathers many values into one, and spread scatters a collection's contents into many values.

Functions that use all three well become far more concise and safer against unexpected input.

Default Parameters

Filling In Values That Aren't Passed

Without default parameters, an argument that isn't passed has the value undefined — and that often makes a function produce strange output. Default parameters set a fallback value used when an argument isn't provided:

JSDefault parameters
function sapa(nama, bahasa = "Indonesia") {
  const halo = bahasa === "Inggris" ? "Hello" : "Halo";
  return `${halo}, ${nama}!`;
}
 
console.log(sapa("Arman"));
console.log(sapa("Arman", "Inggris"));

function sapa(nama, bahasa = "Indonesia") sets "Indonesia" as the default. Calling sapa("Arman") uses the default, so the result is Halo, Arman!, while sapa("Arman", "Inggris") produces Hello, Arman!. The default value only activates when the argument is undefined.

More Complex Defaults

A default value can be any expression, including the result of calling another function:

JSDefault with expressions
function buatId(prefix = "user", nomor = Date.now()) {
  return `${prefix}-${nomor}`;
}
 
console.log(buatId());
console.log(buatId("admin", 7));

buatId() produces a timestamp-based ID, while buatId("admin", 7) produces admin-7. Using Date.now() as a default means the function remains useful without arguments — a good pattern for values that either the caller may choose or are determined automatically.

The Rest Parameter

Capturing Many Arguments

The rest parameter is marked with ... before the parameter name and gathers all extra arguments into an array:

JSRest parameter
function jumlahkan(...angka) {
  let total = 0;
  for (const nilai of angka) {
    total += nilai;
  }
  return total;
}
 
console.log(jumlahkan(1, 2, 3));
console.log(jumlahkan(5, 10, 15, 20));

function jumlahkan(...angka) accepts any number of arguments and stores them in the angka array. jumlahkan(1, 2, 3) returns 6, and the four-argument version returns 50. This replaces the old arguments object, whose behavior was confusing.

Rest with Preceding Parameters

The rest parameter must be the last parameter, and it can be combined with ordinary parameters:

JSRest after fixed parameters
function daftarBelanja(toko, ...item) {
  console.log(`Belanja di: ${toko}`);
  return item.join(", ");
}
 
console.log(daftarBelanja("Toko Bersih", "Beras", "Minyak", "Telur"));

function daftarBelanja(toko, ...item) assigns toko as the first argument and item captures the rest. The result is Belanja di: Toko Bersih then Beras, Minyak, Telur. This pattern is very common for functions that need one required argument and the rest optional.

The Spread Operator

Spreading Arrays

The spread operator (... in front of an array) does the opposite of rest: it scatters a collection's contents into separate values. Its most common use is combining arrays:

JSCombining arrays with spread
const pagi = ["kopi", "telur"];
const siang = ["nasi", "sayur"];
const menu = [...pagi, ...siang];
 
console.log(menu);
console.log([...menu, "makan malam"]);

[...pagi, ...siang] combines two arrays into one without the concat method. Adding elements is also more concise: [...menu, "makan malam"] adds at the end. Spread creates a new array — the original arrays stay unchanged, preventing accidental mutation.

Copying Arrays Safely

Before spread, copying an array with = only duplicated the reference — changing the copy changed the original array. Spread creates a safe shallow copy:

JSCopying arrays with spread
const asli = [1, 2, 3];
const salinan = [...asli];
 
salinan.push(4);
console.log(salinan);
console.log(asli);

salinan.push(4) only changes salinan, while asli stays [1, 2, 3]. The [...asli] pattern is used everywhere to make a copy before mutating. Remember: this is a shallow copy — objects inside the array still share references, which we'll dig deeper into in episode 22.

Spreading Objects and Combining Patterns

Spread on Objects

Spread also works on objects to combine properties or create copies:

JSSpread on objects
const dasar = { nama: "Arman", role: "Engineer" };
const lengkap = { ...dasar, kota: "Jakarta" };
const duplikat = { ...dasar };
 
console.log(lengkap);
console.log(duplikat);

{ ...dasar, kota: "Jakarta" } combines dasar's properties with new properties. If there's a duplicate key, the later value overwrites it — this is the very common config override pattern: { ...defaultConfig, ...userConfig }.

Combining All the Patterns

The three features work together naturally. A classic example: a function that accepts default options and user options:

JSDefault, rest, and spread working together
function buatServer(host = "localhost", ...portRange) {
  const port = portRange[0] ?? 3000;
  const config = { host, port, ssl: false };
  return config;
}
 
const server = buatServer("0.0.0.0", 8080);
console.log(server);

host = "localhost" is a default parameter, ...portRange captures the extra arguments, and the resulting object is assembled neatly. This function handles calls with no arguments, one argument, or two arguments — all without messy conditional lines.

Tip

Remember the direction: rest ... gathers values into an array when writing a function; spread ... scatters an array or object into values when calling or creating a literal. If the output feels "clustered together", it's rest; if "spread apart", it's spread.

Wrap-Up

Episode 7 added three ES6 features that make functions far more professional: default parameters for fallback values, the rest parameter for capturing many arguments, and the spread operator for scattering and combining arrays and objects. All three are often used together in a single function.

Key takeaways:

  • Default parameters are used when an argument is undefined.
  • The rest parameter ... must be the last parameter and produces an array.
  • Spread [...a, ...b] combines arrays without changing the originals.
  • [...asli] and { ...objek } create safe shallow copies.
  • Duplicate object keys in later spread positions overwrite earlier ones.
  • Default, rest, and spread work together for flexible functions.

In the next episode 8 we'll cover arrow functions and higher-order functions — a more concise function syntax with different this behavior, plus the concept of functions that accept or return other functions. This is the gateway into functional programming in JavaScript.

Learn JavaScript - Advanced Functions, Default Parameters, Rest, and Spread | Learn JavaScript