Spread & Rest — JavaScript

Tiga titik ... di JavaScript itu kayak Swiss Army knife — operator simpel yang bisa ngerjain dua hal kebalikan: nyebarin isi, atau ngumpulin item. Spread…

Tiga titik ... di JavaScript itu kayak Swiss Army knife — operator simpel yang bisa ngerjain dua hal kebalikan: nyebarin isi, atau ngumpulin item. Spread nyebarin elemen array atau properti object kayak nuangin ember ke ember lain. Rest ngumpulin sisa argumen kayak nyatuin kerupuk yang berserakan ke piring. Tergantung di sebelah mana ... ditaruh — kanan = spread (tumpah keluar), kiri = rest (masuk dikumpulin).

🤔 Trick paling populer. [...new Set(arr)] — gabungin Set (yang otomatis unique) dengan spread, dapet array tanpa duplikat dalam satu baris. Resep dedupe yang dipake di production code di mana-mana.

Spread — menyebarkan elemen:

// Array
const arr1 = [1, 2];
const arr2 = [3, 4];
const gabungan = [...arr1, ...arr2]; // [1, 2, 3, 4]

// Object
const dasar = { nama: "Budi" };
const lengkap = { ...dasar, umur: 17 }; // { nama: "Budi", umur: 17 }

Rest — mengumpulkan sisa argumen:

function jumlahSemua(...angka) {
  return angka.reduce((acc, n) => acc + n, 0);
}
jumlahSemua(1, 2, 3, 4); // 10

Rest di destructuring:

const [pertama, ...sisanya] = [1, 2, 3, 4];
// pertama = 1, sisanya = [2, 3, 4]

const { nama, ...lainnya } = { nama: "Budi", umur: 17, kota: "Jakarta" };
// nama = "Budi", lainnya = { umur: 17, kota: "Jakarta" }

🎭 Analogi sehari-hari

Tanda ... sama, beda lokasi:

⚠️ Jebakan yang sering ditemui

1. Spread bikin SHALLOW copy — nested object masih shared.

const a = { user: { nama: "Budi" } };
const b = { ...a };
b.user.nama = "Ani";
console.log(a.user.nama);  // "Ani" — kena!

Untuk deep copy: structuredClone(a) atau JSON.parse(JSON.stringify(a)).

2. Rest harus jadi parameter TERAKHIR.

function f(...sisa, akhir) {}    // ❌ SyntaxError
function f(awal, ...sisa) {}     // ✅

3. Object spread menimpa key yang sama — urutan matters.

const a = { x: 1, y: 2 };
const b = { ...a, x: 99 };       // { x: 99, y: 2 } — `x` ditimpa
const c = { x: 99, ...a };       // { x: 1, y: 2 }  — `x` ditimpa balik!

🧪 Tebakan cepat — shallow copy bug. Tanpa run, tebak nilai akhir a.user.nama:

const a = { user: { nama: "Budi" } };
const b = { ...a };
b.user.nama = "Ani";
console.log(a.user.nama);  // ???

Jawaban: "Ani" — bukan "Budi". Spread cuma copy LEVEL ATAS. Object nested (user) sharing reference yang sama antara a dan b. Mutasi b.user.nama = mutasi a.user.nama juga. Bug serem yang sering bikin pusing pas state management. Solusi deep copy: structuredClone(a) atau library lodash cloneDeep.

TL;DR: ... punya 2 fungsi tergantung lokasi: kanan = spread (sebar isi keluar — [...arr], {...obj}, fn(...args)), kiri = rest (kumpulin sisa — function f(...args), const [a, ...sisa]). Spread bikin SHALLOW copy — nested object masih shared (deep copy: structuredClone()). Rest harus parameter TERAKHIR. Object spread urutan matters ({...a, x: 99} timpa a.x). Pattern ini paling sering di state management React/Vue.

Yang akan kamu pelajari