Data asli ikut berubah karena object di JavaScript disalin sebagai reference, bukan sebagai value. Solusi tercepat: ganti assignment langsung const b = a dengan clone. Pakai spread untuk object datar satu level, pakai structuredClone() untuk object bersarang di browser modern dan Node.js.
Kenapa Object Bisa Ikut Berubah Saat Disalin
Primitive seperti number dan string disalin nilainya. Object dan array disalin alamat memorinya. Variabel baru tetap menunjuk ke data yang sama.
Kode ini terlihat menyalin, padahal hanya membuat alias:
const user = { nama: "Andi", alamat: { kota: "Jakarta" } };
const copy = user;
copy.nama = "Budi";
Sekarang user.nama ikut menjadi "Budi". Shallow copy dengan spread hanya aman untuk object datar. Begitu ada nested object, properti dalamnya masih berbagi reference dan gagal melindungi data asli.
Tabel: Kondisi, Penyebab, dan Solusi Cepat
Pilih solusi dari bentuk datanya, bukan dari panjang kodenya.
| Error/Kondisi | Penyebab | Solusi |
|---|---|---|
| Ubah salinan, data asli ikut berubah | Assignment langsung memakai reference sama | Clone dulu sebelum edit |
| Spread dipakai tapi nested object tetap ketimpa | Spread hanya menyalin satu level | Pakai deep copy |
| Object.assign masih menimpa object dalam | Object.assign juga shallow copy | Pakai structuredClone |
- Object datar tanpa nested: spread atau Object.assign cukup.
- Object bersarang, array of object, form state: wajib deep copy.
- Data dari Fetch/API sebelum dimutasi: clone dulu, lalu ubah salinannya.
Cara Memperbaiki dengan Clone yang Benar
Ikuti urutan ini agar tidak salah pilih clone:
1. Periksa struktur object. Ada properti object atau array di dalamnya.
2. Kalau datar, salin dengan spread.
3. Kalau bersarang, salin dengan structuredClone().
4. Kalau runtime lama dan data hanya JSON polos, pakai JSON.parse(JSON.stringify()).
// SALAH: nested masih berbagi reference
const salah = { ...user };
salah.alamat.kota = "Bandung";
// BENAR: nested ikut disalin
const benar = structuredClone(user);
benar.alamat.kota = "Bandung";
Baris spread hanya membuat object luar baru. alamat di dalamnya tetap menunjuk ke object lama. Baris structuredClone membuat salinan penuh sampai ke dalam, sehingga perubahan kota tidak menyentuh user asli.
structuredClonetersedia di browser modern dan Node.js versi baru.- Metode JSON gagal untuk function, Date, undefined, Map, Set, dan circular reference.
- Metode JSON mengubah Date menjadi string.
Cara Mencegah Data Asli Tertimpa Lagi
- Clone selalu sebelum mengedit state, props, atau response API.
- Buat fungsi murni: terima object, kembalikan object baru, jangan ubah argumen.
- Hindari
push,splice, atau assignment langsung ke object milik komponen lain. - Ingat: spread dan Object.assign adalah shallow copy, bukan deep clone.
- Cek hasil clone dengan mengubah salinan lalu membaca ulang data asli.
FAQ
Apakah spread operator memutus reference object?
Hanya untuk satu level teratas; nested object masih berbagi reference.
Kapan harus pakai deep copy untuk object?
Pakai deep copy setiap object berisi object, array, atau data bertingkat lain.
Kenapa JSON.parse(JSON.stringify()) kadang gagal?
Metode itu tidak mendukung function, Date, undefined, Map, Set, dan circular reference.