Ganti let b = a dengan salinan eksplisit seperti [...a], a.slice(), atau structuredClone(a) bila isinya objek bersarang. Assignment array di JavaScript tidak menduplikasi isi, variabel baru hanya menunjuk ke memori yang sama sehingga push, splice, sort, atau ubahan properti objek langsung terlihat di array asli.
Kenapa Array Salinan Ikut Mengubah Array Asli
Array adalah tipe referensi. Variabel menyimpan alamat memori, bukan salinan nilainya.
let b = amembuat dua nama untuk satu array yang sama.- Method mutasi seperti
push(),splice(),sort(), danreverse()mengubah array di tempat. - Jika elemennya objek, mengubah
b[0].namajuga mengubaha[0].namakarena objek di dalamnya masih satu referensi.
Ini termasuk logic error, bukan TypeError atau SyntaxError. Kode tetap jalan, tetapi data berubah tanpa disadari.
Tabel: Kondisi, Penyebab, dan Solusi Cepat
| Kondisi | Penyebab | Solusi |
|---|---|---|
| Assignment langsung | let b = a menyalin referensi |
Gunakan [...a] atau a.slice() |
| Mutasi method | sort, splice, push mengubah data asli |
Salin dulu sebelum mutasi |
| Nested object | Shallow copy hanya menyalin level pertama | Pakai structuredClone() |
| Parameter function | Array dikirim sebagai referensi | Salin di dalam function sebelum diubah |
Shallow copy aman untuk array flat berisi string atau angka. Shallow copy gagal untuk array berisi objek atau array lain.
Cara Memperbaiki Array yang Terlanjur Satu Referensi
Ikuti urutan ini agar bug tidak terulang:
- Reproduksi bug dengan mencetak array asli sebelum dan sesudah perubahan.
- Ganti assignment langsung dengan metode salinan sesuai bentuk data.
- Tangani objek bersarang secara khusus karena spread tidak cukup.
// SALAH: satu referensi
let a = [1, 2, 3];
let b = a;
b.push(4);
console.log(a); // [1, 2, 3, 4]
// BENAR: array flat
let c = [...a];
let d = a.slice();
let e = Array.from(a);
// BENAR: array berisi objek
let users = [{ nama: "Andi" }];
let salinan = structuredClone(users);
let salinanMap = users.map(u => ({ ...u }));
[...a]: paling ringkas untuk array flat.slice(): cocok bila gaya kode menghindari spread.Array.from(a): berguna untuk array-like sebelum diproses.map()plus spread objek: praktis untuk menyalin satu level objek.structuredClone(): pilihan langsung untuk deep copy modern di browser dan Node.js baru.
Cara Mencegah Referensi Ikut Berubah Lagi
- Salin array sebelum
sort(),reverse(),splice(), ataupush(). - Gunakan
toSorted()dantoSpliced()bila runtime mendukung karena keduanya mengembalikan array baru tanpa mengubah array lama. - Untuk data bersarang, gunakan
structuredClone()atau salin manual tiap level yang akan dimutasi. - Buat aturan di function: jangan memutasi parameter array, selalu buat salinan lokal.
FAQ
Kenapa spread kadang objek di dalamnya masih ikut berubah?
Spread hanya menyalin level pertama, objek di dalamnya tetap memakai referensi yang sama.
Kapan cukup memakai slice dan kapan perlu deep copy?
slice() cukup untuk array berisi string, angka, atau boolean; gunakan deep copy bila elemennya objek atau array.
Apakah const mencegah array berubah?
Tidak, const hanya mencegah assignment ulang variabel, isi array tetap bisa dimutasi.