Spread dan Rest Operator (...)
Tiga titik ajaib: spread untuk menyebar isi array/object, rest untuk mengumpulkan sisa argumen.
Satu simbol, dua peran
Operator ... (tiga titik) punya dua peran tergantung posisi. Sebagai spread, ia menyebar isi array/object. Sebagai rest, ia mengumpulkan sisa nilai. Namanya ditentukan dari fungsinya, bukan simbolnya.
Spread: menyebar isi
let a = [1, 2];
let b = [3, 4];
let gabung = [...a, ...b];
console.log(gabung); // [1, 2, 3, 4]
let user = { nama: "Rizky" };
let userLengkap = { ...user, umur: 17 };
console.log(userLengkap); // { nama: "Rizky", umur: 17 }Spread juga cara termudah menyalin array/object tanpa berbagi referensi:
let asli = [1, 2, 3];
let salinan = [...asli]; // salinan mandiriRest: mengumpulkan sisa
Saat ... dipakai di parameter fungsi atau destructuring, ia mengumpulkan sisa nilai menjadi array:
function total(...angka) {
return angka.reduce((a, b) => a + b, 0);
}
console.log(total(1, 2, 3, 4)); // 10
let [pertama, ...sisanya] = [1, 2, 3, 4];
console.log(pertama); // 1
console.log(sisanya); // [2, 3, 4]Cara membedakan
Aturan sederhana: kalau ... dipakai untuk memecah sesuatu yang sudah ada menjadi bagian-bagian, itu spread. Kalau dipakai untuk mengumpulkan banyak nilai menjadi satu, itu rest.
// spread: memecah array jadi argumen terpisah
let angka = [5, 10, 15];
console.log(Math.max(...angka)); // 15
// rest: mengumpulkan argumen jadi array
function daftar(...item) { return item; }Catatan teknis: Spread hanya shallow copy. Untuk object bersarang, properti dalamnya masih berbagi referensi: const b = {...a}; b.data.x = 1 akan mengubah a.data.x juga. Untuk clone dalam, pakai structuredClone().
Studi kasus: update state immutable
Di aplikasi modern (React dan sejenisnya), state tidak boleh diubah langsung. Spread memungkinkan "mengubah" dengan membuat salinan baru:
let user = { nama: "Rizky", umur: 17, kota: "Bandung" };
// update umur tanpa mengubah object asli
let userBaru = { ...user, umur: 18 };
console.log(user.umur); // 17, asli utuh
console.log(userBaru.umur); // 18
// tambah item ke array tanpa push ke array asli
let list = ["a", "b"];
let listBaru = [...list, "c"];
console.log(list); // ["a", "b"]
console.log(listBaru); // ["a", "b", "c"]Pola ini membuat perubahan data mudah dilacak karena data lama tidak pernah berubah. Ini fondasi cara kerja state di framework modern.
Kesimpulan
Spread untuk menyebar dan menyalin, rest untuk mengumpulkan. Keduanya memakai simbol sama tapi peran berlawanan. Kuasai keduanya karena mereka ada di hampir setiap file JavaScript modern.