Ketika kita menyalin objek menggunakan spread { ...obj } atau Object.assign, yang kita dapatkan hanyalah shallow copy. Nilai di lapisan pertama memang tersalin, tapi objek atau array yang bersarang di dalamnya masih menunjuk ke reference yang sama. Jadi bila kita mengubah bagian yang bersarang tadi, data aslinya ikut berubah.
Bayangkan kita punya objek user dengan alamat di dalamnya:
const user = { nama: 'Nauval', alamat: { kota: 'Jakarta' } };
const salinan = { ...user };
salinan.alamat.kota = 'Bandung';
console.log(user.alamat.kota); // "Bandung" ๐ฆObjek alamat tidak ikut disalin, yang tersalin cuma reference-nya. Untuk benar-benar memisahkan salinan dari aslinya, kita butuh deep copy.
Dulu triknya pakai JSON.parse(JSON.stringify(obj)), tapi cara itu punya banyak masalah. Date berubah jadi string, undefined dan function hilang, lalu Map atau Set tidak terbawa.
Sekarang browser sudah punya structuredClone bawaan:
const user = { nama: 'Nauval', alamat: { kota: 'Jakarta' }, dibuat: new Date() };
const salinan = structuredClone(user);
salinan.alamat.kota = 'Bandung';
console.log(user.alamat.kota); // "Jakarta" โ
console.log(salinan.dibuat instanceof Date); // truestructuredClone menyalin sampai ke dalam, dan tetap menjaga tipe seperti Date, Map, Set, sampai ArrayBuffer.
Satu hal yang perlu diingat, dia tidak bisa menyalin function. Bila di dalam objekmu ada method atau function, structuredClone bakal melempar error. Tapi untuk data biasa seperti hasil fetch, state, atau konfigurasi, ini sudah lebih dari cukup.