Spread dan Rest JavaScript: Memahami Operator ...

Tiga titik yang punya dua tugas berlawanan. Pelajari cara operator spread membongkar array dan objek, cara rest parameter mengumpulkan argumen tambahan jadi satu array, dan cara membedakan keduanya.

Diterbitkan 4 Agustus 202610 menit bacaOleh ACY Partner Indonesia
Spread dan rest JavaScript — operator tiga titik
300 × 250Slot Iklan TersediaPasang iklan Anda di sini

Ada satu potongan sintaks JavaScript modern yang bakal terus kamu temui begitu mulai membaca kode beneran: tiga titik, .... Dia muncul saat menyalin array, menggabungkan dua objek, mengoper sederet argumen, atau mengumpulkan “sisanya yang lain” ke dalam satu variabel. Yang bikin bingung, tiga titik yang sama itu ternyata melakukan dua hal yang berlawanan, tergantung di mana kamu menulisnya. Di satu tempat dia membongkar sebuah kumpulan; di tempat lain dia justru mengumpulkan nilai-nilai yang berserakan. Artikel ini akan menuntaskan kebingungan itu.

Kedua perilaku tadi punya nama. Saat ... membuka sesuatu menjadi potongan-potongan terpisahnya, itu namanya operator spread. Saat dia mengumpulkan beberapa nilai jadi satu array, itu elemen rest. Simbolnya sama, tapi tugasnya kebalikan satu sama lain. Kita bahas satu per satu, dengan banyak contoh nyata, dan di akhir artikel kamu bakal selalu tahu sedang melihat yang mana.

Kalau kamu masih perlu membiasakan diri dengan struktur datanya sendiri, ada baiknya membaca dulu array dan objek serta fungsi — semua yang ada di sini berdiri langsung di atas keduanya.

Apa sih sebenarnya yang dilakukan tiga titik ini

Sebelum hafal namanya, pegang dulu satu ide sederhana. Sintaks ... selalu duduk di sebelah sebuah kumpulan atau variabel, dan arahnya ditentukan oleh konteks:

  • Di sisi kanan sebuah assignment, atau di dalam [ ] / { } / pemanggilan fungsi, dia menyebar (spread) — membuka sebuah kumpulan dan menjajarkan isinya satu per satu.
  • Di sisi kiri, di dalam daftar parameter fungsi atau sebuah pola destructuring, dia mengumpulkan (rest) — menciduk nilai-nilai sisa ke dalam array baru.

Cuma itu intinya. “Aku ini sedang menyusun sesuatu dari potongan-potongan, atau sedang menangkap potongan ke dalam wadah?” Jawab pertanyaan itu, maka kamu langsung tahu sedang spread atau rest. Yuk kita lihat keduanya beraksi.

Operator spread: membongkar sebuah kumpulan

Operator spread mengambil sebuah iterable — paling sering berupa array — lalu menyebarkan isinya seolah-olah kamu mengetik tiap elemen satu per satu. Tempat paling gampang untuk merasakannya adalah saat menyusun array:

const numbers = [1, 2, 3];
const more = [...numbers, 4, 5];

console.log(more);   // [1, 2, 3, 4, 5]

...numbers bukan menaruh array-nya di dalam array baru — dia menuangkan isinya. Jadi more jadi [1, 2, 3, 4, 5], bukan [[1, 2, 3], 4, 5]. Perbedaan ini adalah inti dari spread: dia membuka satu lapisan.

Menyalin array

Salah satu pemakaian paling umum adalah membuat salinan dangkal (shallow copy) sebuah array. Karena spread menjajarkan elemen-elemen baru ke dalam array yang benar-benar baru, salinannya jadi terpisah dari aslinya:

const asli = ["a", "b", "c"];
const salinan = [...asli];

salinan.push("d");

console.log(asli);      // ["a", "b", "c"]  (tetap utuh)
console.log(salinan);   // ["a", "b", "c", "d"]

Ini penting karena const salinan = asli tidak menyalin apa pun — kedua nama itu bakal menunjuk ke array yang sama persis, dan menambah isi yang satu otomatis mengubah yang lain. Spread memberimu array yang benar-benar berdiri sendiri.

Menggabungkan array

Mau menyatukan beberapa array sekaligus? Spread masing-masing di dalam sebuah array literal baru:

const depan = [1, 2];
const belakang = [3, 4];

const gabungan = [...depan, ...belakang];
console.log(gabungan);   // [1, 2, 3, 4]

// kamu bisa menyelipkan nilai tambahan di mana saja
const dilengkapi = [0, ...depan, 99, ...belakang];
console.log(dilengkapi); // [0, 1, 2, 99, 3, 4]

Cara ini terbaca rapi dan kamu mengatur urutannya dengan presisi — jauh lebih enak ketimbang pendekatan lama dengan concat.

Spread pada objek

Spread juga jalan di objek (sejak ES2018), menyalin pasangan key-value-nya ke dalam objek baru. Inilah cara modern untuk mengkloning atau memperluas sebuah objek:

const user = { name: "John Doe", role: "editor" };

const updated = { ...user, role: "admin" };

console.log(updated);   // { name: "John Doe", role: "admin" }
console.log(user);      // { name: "John Doe", role: "editor" }  (tetap utuh)

Di sini ...user menyalin semua property milik user ke objek baru, baru setelah itu role: "admin" diterapkan. Urutannya berpengaruh: key yang ditulis belakangan yang menang, jadi updated mempertahankan name tapi menimpa role. Objek user aslinya dibiarkan persis seperti semula — ini pola standar untuk “beri aku salinan objek ini dengan satu field diubah,” yang akan kamu pakai di mana-mana, mulai dari state React sampai payload API.

Salinan dari spread itu dangkal

Spread cuma menggandakan lapisan paling atas. Kalau ada nilai di dalam array atau objek yang ternyata berupa array atau objek lagi, salinannya tetap berbagi referensi bersarang yang sama dengan aslinya.

const a = { name: "John Doe", tags: ["x", "y"] };
const b = { ...a };

b.tags.push("z");
console.log(a.tags);   // ["x", "y", "z"]  ← yang asli ikut berubah!

b memang dapat objek sendiri di lapisan atas, tapi b.tags dan a.tags masih array yang sama persis. Untuk salinan dalam (deep copy) yang benar-benar terpisah, kamu butuh kloning dalam yang disengaja (misalnya structuredClone(a) di lingkungan modern). Untuk data yang datar, salinan dangkal justru pas — kamu cuma perlu sadar di mana batasnya.

Spread ke dalam pemanggilan fungsi

Spread juga bekerja di tempat kamu memanggil fungsi, mengubah sebuah array jadi sederet argumen terpisah. Ini cocok banget untuk fungsi yang mengharapkan nilai satu-satu, seperti Math.max:

const nilai = [82, 96, 71, 88];

console.log(Math.max(...nilai));   // 96
// setara dengan Math.max(82, 96, 71, 88)

Math.max tidak menerima array — dia maunya argumen satu demi satu. Spread pada array tadi menyerahkan tiap elemen sebagai argumennya masing-masing. Sebelum sintaks ini ada, orang memakai Math.max.apply(null, nilai); spread melakukan hal yang sama tapi jauh lebih enak dibaca.

Rest: mengumpulkan nilai ke dalam array

Sekarang balik arahnya. Rest muncul di sisi penerima dan melakukan kebalikan dari spread: alih-alih membuka sebuah kumpulan, dia justru mengumpulkan nilai-nilai yang berserakan ke dalam satu array. Kamu akan menemuinya di dua tempat — parameter fungsi dan destructuring.

Rest parameter di dalam fungsi

Misalkan kamu ingin sebuah fungsi yang menjumlahkan berapa pun banyaknya angka yang diberikan — dua, lima, dua puluh, kamu nggak tahu dari awal. Sebuah rest parameter menangkap semua argumen ke dalam satu array sungguhan:

function jumlah(...nums) {
  let total = 0;
  for (const n of nums) {
    total += n;
  }
  return total;
}

console.log(jumlah(1, 2, 3));        // 6
console.log(jumlah(10, 20, 30, 40)); // 100
console.log(jumlah());               // 0

Di dalam jumlah, nums adalah array biasa yang berisi setiap argumen yang dioper, jadi kamu bisa me-loop-nya, memanggil .length, memakai method array — apa saja. ... di sini mengumpulkan, persis kebalikan dari pemanggilan spread yang baru saja kita lihat.

Kamu juga boleh menaruh parameter tetap di depan, lalu membiarkan rest mengepel sisanya. Rest parameter harus berada di paling akhir:

function sapa(salam, ...names) {
  return names.map((n) => `${salam}, ${n}!`);
}

console.log(sapa("Hai", "John Doe", "Jane Doe"));
// ["Hai, John Doe!", "Hai, Jane Doe!"]

salam mengambil argumen pertama; ...names mengumpulkan semua sisanya ke dalam array. Bersih dan jelas.

Rest parameter mengungguli objek arguments lama

JavaScript versi lama menyediakan objek khusus bernama arguments di dalam setiap fungsi untuk menjangkau argumen tambahan. Rest parameter lebih unggul di semua sisi yang penting: ...nums itu array betulan (jadi .map, .filter, .reduce langsung bisa dipakai), sedangkan arguments cuma objek yang mirip array dan harus kamu konversi dulu. Rest juga jalan di dalam arrow function, tempat arguments justru tidak ada sama sekali. Di kode baru, pilih rest parameter dan anggap saja arguments itu tidak ada.

Rest di dalam destructuring

Ide yang sama berlaku saat kamu menarik nilai keluar dari sebuah array atau objek. Rest menyambar “semua yang tidak aku sebut satu per satu.” Pada array:

const [pertama, kedua, ...sisanya] = [10, 20, 30, 40, 50];

console.log(pertama);   // 10
console.log(kedua);     // 20
console.log(sisanya);   // [30, 40, 50]

pertama dan kedua mengambil dua item awal; ...sisanya mengumpulkan item-item yang tersisa ke dalam array baru. Ini cara yang rapi untuk memisahkan “kepala” dari “ekor” sebuah daftar.

Pada objek juga bisa, di mana rest mengumpulkan property yang tersisa ke dalam objek baru:

const orang = { name: "Jane Doe", age: 31, city: "Jakarta", role: "admin" };

const { name, ...rest } = orang;

console.log(name);   // "Jane Doe"
console.log(rest);   // { age: 31, city: "Jakarta", role: "admin" }

Satu kegunaan praktisnya: ini cara paling bersih untuk membuang sebuah property dari objek tanpa mengubah aslinya. Tarik keluar key yang mau kamu hilangkan, dan rest memegang semua sisanya.

// buang password sebelum mengirim objek user ke client
const { password, ...userAman } = userLengkap;
// userAman punya semua field kecuali password

Spread vs rest: cara membedakannya

Tiga titiknya sama, lalu bagaimana cara langsung tahu yang mana yang sedang kamu baca? Lihat dia ada di sisi mana dari sebuah aksi:

  • Spread ada di sisi nilai/output. Dia berada di dalam sesuatu yang sedang kamu susun: array literal [ ], objek literal { }, atau argumen pada pemanggilan fungsi. Dia membongkar sebuah kumpulan.
  • Rest ada di sisi penerima. Dia berada di tempat nilai-nilai diterima: daftar parameter sebuah fungsi, atau sisi kiri sebuah assignment destructuring. Dia mengemas nilai-nilai jadi satu.

Baca saja sebagai pertanyaan: Apakah ini membuka sebuah kumpulan jadi potongan-potongan (spread), atau menangkap potongan-potongan ke dalam sebuah kumpulan (rest)? Posisinya selalu menjawabnya.

// SPREAD — membongkar, di sisi penyusunan
const all = [...a, ...b];        // di dalam array literal
fn(...args);                     // di dalam pemanggilan fungsi

// REST — mengumpulkan, di sisi penerima
function fn(...args) { }          // di daftar parameter
const [head, ...tail] = list;    // di pola destructuring

Satu simbol, dua peran — itu wajar

Memang terasa aneh kalau satu operator berarti dua hal yang berlawanan. Tapi perhatikan, keduanya tidak pernah bertabrakan: spread cuma masuk akal di tempat kamu menyusun sebuah nilai, dan rest cuma masuk akal di tempat kamu menerima sebuah nilai. Konteks tempat keduanya hidup tidak pernah tumpang tindih, jadi JavaScript (dan kamu) selalu bisa membedakan mana yang dimaksud. Bersandarlah pada aturan posisi tadi, dan kebingungannya hilang.

Beberapa pola nyata yang bakal sering kamu pakai

Idiom-idiom kecil ini muncul berulang kali, jadi sebaiknya kamu langsung kenal begitu melihatnya:

// 1. Kloning-lalu-ubah sebuah objek (ramah immutability)
const stateBaru = { ...state, loading: false };

// 2. Menambah item ke array tanpa mengubah aslinya
const denganBaru = [...items, itemBaru];

// 3. Mengubah iterable apa pun jadi array betulan (string → huruf, Set → array)
const huruf = [...("hello")];          // ["h", "e", "l", "l", "o"]
const unik = [...new Set([1, 1, 2, 3, 3])];  // [1, 2, 3]

// 4. Memberi fungsi argumen yang fleksibel
function catatSemua(label, ...pesan) {
  pesan.forEach((m) => console.log(label, m));
}

Yang nomor tiga itu trik manis: spread pada sebuah Set adalah cara terpendek untuk menghapus duplikat dari array, karena Set otomatis membuang nilai kembar dan spread mengubahnya balik jadi array biasa.

Penutup

Tiga titik, dua tugas berlawanan — dan sekarang kamu selalu bisa membedakannya:

  • Spread (...) membuka sebuah kumpulan jadi potongan-potongan terpisah. Pakai di dalam array literal, objek literal, dan pemanggilan fungsi untuk menyalin, menggabungkan, dan membongkar: [...arr], { ...obj }, fn(...args), Math.max(...nums).
  • Rest (...) mengumpulkan nilai-nilai yang berserakan jadi satu array. Pakai di parameter fungsi (function f(...args)) dan di destructuring (const [pertama, ...sisanya] = list) untuk menampung “semua yang lain.”
  • Posisinya yang memberitahu mana yang mana: sedang menyusun sebuah nilai → spread; sedang menerima nilai → rest.
  • Salinan dari spread itu dangkal — array/objek bersarang tetap berbagi dengan aslinya. Pakai structuredClone kalau kamu benar-benar butuh salinan dalam.
  • Spread adalah cara modern untuk update yang immutable: salin-dulu-baru-ubah, bukan mengubah di tempat.

Spread dan rest ada di mana-mana di JavaScript modern dan di framework yang dibangun di atasnya, jadi kelancaranmu di sini langsung membuahkan hasil. Keduanya berpasangan secara alami dengan destructuring — menarik nilai keluar dari array dan objek berdasarkan bentuknya — yang jadi materi paling pas untuk kamu kuasai berbarengan.

Tag:javascriptfrontendspreadrestes2015menengah
728 × 90Slot Iklan TersediaPasang iklan Anda di sini

Artikel Terkait

Lihat Semua Artikel

Artikel yang Mungkin Kamu Suka

Apa Itu Framework Frontend? — chip kode dengan tag komponen
Frontend / Dasar

Apa Itu Framework Frontend?

Penjelasan ramah untuk pemula tentang apa itu framework frontend, kenapa mereka ada, masalah apa yang mereka selesaikan dibanding JavaScript biasa, dan kapan kamu memang sebaiknya memakainya.

20 Sep 20268 menit baca
Sampul fundamentals frontend bertuliskan Apa Itu Frontend dan HTML + CSS + JS
Frontend / Dasar

Apa Itu Frontend Development?

Panduan ramah pemula tentang frontend development: bagian website yang kamu lihat dan klik secara langsung. Pahami cara kerja HTML, CSS, dan JavaScript, serta bedanya frontend dengan backend.

20 Sep 20268 menit baca
Ilustrasi sampul untuk Apa yang Dikerjakan Frontend Developer
Frontend / Dasar

Apa yang Dikerjakan Frontend Developer: Panduan untuk Pemula

Penjelasan ramah pemula tentang apa yang sebenarnya dikerjakan frontend developer setiap hari: mengubah desain jadi antarmuka yang berfungsi, membangun UI yang bisa dipakai ulang, sampai urusan responsif, aksesibilitas, dan kecepatan.

20 Sep 20269 menit baca
Kartu judul bertuliskan Styling dan Interaktivitas di atas latar biru gelap ACY Partner
Frontend / Dasar

Cara Kerja Styling dan Interaktivitas

Penjelasan ramah pemula soal bagaimana CSS menyulap HTML polos jadi tampilan rapi, dan bagaimana JavaScript menambahkan perilaku — pola berpikir struktur, gaya, perilaku saat membangun halaman web.

20 Sep 20268 menit baca
Tiga lapisan front-end menyatu di satu halaman web
Frontend / Dasar

Cara HTML, CSS, dan JavaScript Bekerja Bersama

Panduan praktis untuk pemula: bikin satu tombol kecil, beri struktur dengan HTML, tampilan dengan CSS, dan perilaku dengan JavaScript, lalu lihat ketiga lapisan ini bekerja sama di halaman nyata.

20 Sep 20268 menit baca
Sampul ikhtisar praktik terbaik frontend
Frontend / Dasar

Ikhtisar Praktik Terbaik Frontend

Peta ringkas tentang apa itu frontend yang baik — HTML bermakna, CSS rapi, JavaScript secukupnya, desain responsif, performa, dan progressive enhancement, lengkap dengan arahan untuk mendalaminya.

20 Sep 20268 menit baca