Section ini sudah memberi kita puluhan method array: yang menambah, menghapus, mencari, mengubah, merangkum, dan mengurutkan. Dengan banyaknya pilihan, keputusan harian bergeser dari “bagaimana caranya” menjadi “yang mana yang tepat” — memilih includes atau find, mengubah array asal atau bekerja pada salinan. Keputusan yang keliru jarang menimbulkan error; akibatnya muncul jauh dari tempat kesalahannya, misalnya array konfigurasi yang tiba-tiba tersusun ulang karena disortir tanpa sengaja.
Chapter penutup ini merangkum tiga keputusan itu: memilih method sesuai tujuan, mengendalikan mutasi dengan salinan, dan mengubah nilai yang menyerupai array menjadi array sungguhan.
Memilih Method Sesuai Tujuan #
Langkah pertama sebelum menulis kode adalah menyebut hasil akhir yang diinginkan. Tabel berikut memetakan kebutuhan yang paling sering muncul ke method yang tepat:
| Kebutuhan | Method | Hasil |
|---|---|---|
| Mengubah bentuk tiap elemen | map | array baru, panjang sama |
| Menyaring berdasarkan kriteria | filter | array baru, panjang bisa berbeda |
| Merangkum menjadi satu nilai | reduce | satu nilai |
| Mengambil satu elemen tertentu | find | elemen atau undefined |
| Mengambil posisi berdasarkan kondisi | findIndex | index atau -1 |
| Mengecek keberadaan nilai persis | includes | true / false |
| Mengambil posisi nilai persis | indexOf | index atau -1 |
| Memeriksa sebagian / seluruh elemen | some / every | true / false |
| Mengambil potongan atau menggabung | slice / concat | array baru |
| Menyisipkan atau menghapus di tengah | splice | array asal berubah |
| Mengurutkan atau membalik | toSorted / toReversed | array baru |
Dua baris pertama tabel menjawab mayoritas kasus pengolahan data, dan kombinasi tiga method transformasi sudah kita rangkai di chapter map, filter, dan reduce. Baris terakhir sengaja memakai versi to* — alasannya ada di bagian berikutnya.
Method yang Mengubah vs yang Menyalin #
Semua method array terbagi dua kubu, dan garis batasnya penting. Kubu pertama bermutasi: ia mengubah array pemanggilnya — push, pop, shift, unshift, splice, sort, dan reverse. Kubu kedua menyalin: ia mengembalikan array atau nilai baru dan membiarkan asalnya utuh — slice, concat, map, filter, flat, flatMap, toSorted, toReversed, dan with.
Aturan praktisnya satu kalimat: bila array asal masih akan dipakai lagi, jangan panggil method kubu mutasi langsung atas array tersebut. Ada dua jalan keluar — salin dulu lalu mutasi salinannya, atau pakai varian salin to*:
const angkaAcak = [30, 10, 20];
const terurut = [...angkaAcak].sort((a, b) => a - b);
console.log(terurut);
console.log(angkaAcak);
console.log(angkaAcak.toSorted((a, b) => a - b));
console.log(angkaAcak);Output yang Dihasilkan:
[ 10, 20, 30 ]
[ 30, 10, 20 ]
[ 10, 20, 30 ]
[ 30, 10, 20 ]Tanda [...angkaAcak] membuat array baru yang berisi salinan seluruh elemen; sort kemudian bermutasi pada salinan itu, dan angkaAcak tetap [ 30, 10, 20 ]. Varian toSorted mencapai hasil yang sama dengan satu panggilan. Dua jalan ini setara hasilnya; pilih satu dan konsisten. Yang harus dihindari adalah memanggil sort atau reverse langsung pada array yang masih dipakai bagian program lain.
Salinan Dangkal: Batas yang Perlu Diketahui #
Baik slice(), [...array], maupun toSorted() semuanya membuat salinan dangkal (shallow copy) — hanya lapis terluar yang disalin. Untuk array berisi nilai primitif, ini tidak masalah. Untuk array berisi object, salinan dangkal menyalin referensinya saja, sehingga object di dalam tetap dibagi antara array asal dan salinannya:
const asli = [{ stok: 5 }];
const salinan = asli.slice();
salinan[0].stok = 0;
console.log(salinan[0].stok);
console.log(asli[0].stok);Output yang Dihasilkan:
0
0Yang diubah hanyalah salinan[0], tetapi asli[0].stok ikut berubah menjadi 0 — kedua array memegang referensi object yang sama. Kesadaran akan batas ini mencegah bug halus saat menyalin daftar produk atau daftar pengguna. Cara menyalin object itu sendiri, beserta pengertian referensi secara menyeluruh, adalah inti section Objects.
Callback yang Tenang: Tanpa Efek Samping #
Callback pada map, filter, find, dan kawan-kawannya paling aman bila murni: menerima elemen, mengembalikan nilai, tanpa mengubah apa pun di luar dirinya. Callback yang sambil mengubah variabel lain atau array asal membuat alur data sulit dilacak — akibatnya biasanya muncul jauh dari tempat mutasinya, saat data ternyata sudah berbentuk lain.
Bila transformasi memang membutuhkan efek samping — mencetak, menulis ke luar, atau mengubah data lain — tulis langkahnya eksplisit: simpan hasil map atau filter ke konstanta, lalu proses dengan loop for...of di baris terpisah. Niat program terbaca jauh lebih jelas daripada disembunyikan di dalam callback.
Menamai Array dan Salinannya #
Kebiasaan penamaan yang konsisten menolong saat array dan salinannya hidup berdampingan: keranjang untuk asal, salinanKeranjang untuk hasilnya; angkaAcak dan terurut di contoh babak ini mengikuti pola yang sama. Nama yang menyebut statusnya — acak, terurut, salinan — membuat pembaca tidak perlu membuka isi variabel untuk tahu apa yang dipegangnya.
Mengubah Iterable Menjadi Array #
Terkadang yang kita pegang bukan array sungguhan, melainkan iterable — struktur yang bisa ditelusuri for...of tetapi tidak memiliki method array. String adalah contohnya: ia bisa diloop per karakter, tetapi tidak punya map atau filter. Array.from mengubah iterable menjadi array; operator spread ... mencapai hal yang sama:
const hurufNama = Array.from("Siti");
console.log(hurufNama);
const hurufLain = [..."Budi"];
console.log(hurufLain);Output yang Dihasilkan:
[ 'S', 'i', 't', 'i' ]
[ 'B', 'u', 'd', 'i' ]Kini kedua string menjadi array huruf dengan seluruh method array siap dipakai. Array.from punya satu kemampuan tambahan: argumen kedua berupa callback yang sekaligus memetakan setiap elemen — mirip map yang menyatu. Callback-nya menerima elemen dan index; parameter pertama boleh dinamai _ ketika elemennya memang tidak dipakai, semacam konvensi penamaan untuk “diabaikan”:
const nomorKursi = Array.from({ length: 3 }, (_, i) => `Kursi-${i + 1}`);
console.log(nomorKursi);Output yang Dihasilkan:
[ 'Kursi-1', 'Kursi-2', 'Kursi-3' ]Argumen pertamanya, { length: 3 }, adalah object literal ringan yang hanya membawa properti length — cukup bagi Array.from untuk tahu berapa elemen yang perlu dibentuk. Pola ini praktis untuk membuat deret bernomor tanpa menulis loop. Konversi semacam ini juga menjadi jembatan ketika kita nanti menerima hasil DOM — seperti kumpulan elemen dari querySelectorAll di section DOM — yang berupa iterable, bukan array.
Contoh Lengkap: Keputusan dalam Satu Berkas #
// array-best-practices.js
// Memilih method yang tepat, menyalin sebelum mutasi, mengubah iterable jadi array.
// --- 1. Pilih method sesuai tujuan ---
const stokBuah = ["Apel", "Jeruk", "Mangga", "Jeruk"];
console.log(stokBuah.includes("Jeruk")); // cukup tahu ada atau tidak
console.log(stokBuah.indexOf("Jeruk")); // butuh posisi pertamanya
const semuaPendek = stokBuah.every((buah) => buah.length <= 6);
console.log(semuaPendek);
// --- 2. Salin dulu, baru mutasi: asal tetap utuh ---
const keranjang = ["Buku", "Pulpen"];
const salinanKeranjang = keranjang.slice(); // salinan dangkal (shallow copy)
salinanKeranjang.push("Penghapus");
console.log(salinanKeranjang);
console.log(keranjang);
// Mengurutkan lewat salinan, bukan array asal
const angkaAcak = [30, 10, 20];
const terurut = [...angkaAcak].sort((a, b) => a - b);
console.log(terurut);
console.log(angkaAcak);
// ES2023 menyediakan jalan pintas yang sama: toSorted
console.log(angkaAcak.toSorted((a, b) => a - b));
console.log(angkaAcak);
// --- 3. Mengubah iterable menjadi array ---
const hurufNama = Array.from("Siti");
console.log(hurufNama);
const hurufLain = [..."Budi"];
console.log(hurufLain);
// Argumen kedua Array.from sekaligus memetakan isinya
const nomorKursi = Array.from({ length: 3 }, (_, i) => `Kursi-${i + 1}`);
console.log(nomorKursi);Output yang Dihasilkan:
true
1
true
[ 'Buku', 'Pulpen', 'Penghapus' ]
[ 'Buku', 'Pulpen' ]
[ 10, 20, 30 ]
[ 30, 10, 20 ]
[ 10, 20, 30 ]
[ 30, 10, 20 ]
[ 'S', 'i', 't', 'i' ]
[ 'B', 'u', 'd', 'i' ]
[ 'Kursi-1', 'Kursi-2', 'Kursi-3' ]Mari kita telaah baris-baris pentingnya:
- Baris 5–6 (
includeslaluindexOf): pertanyaan “adakahJeruk?” dijawabtruetanpa posisi; pertanyaan “di mana?” dijawab index1. Dua method, dua bentuk jawaban — pilih sesuai yang dibutuhkan. - Baris 9 (
stokBuah.every((buah) => buah.length <= 6)): pemeriksaan kondisi atas seluruh array; semua nama berpanjang enam huruf atau kurang, sehingga hasilnyatrue. - Baris 14–17 (
slice()lalupushpada salinan):pushmenambah"Penghapus"hanya padasalinanKeranjang; baris berikutnya menunjukkankeranjangtetap dua elemen. - Baris 22–24 (
[...angkaAcak].sort(...)): salinan spread diurutkan, asal tetap[ 30, 10, 20 ]— pola aman ketika varianto*tidak tersedia. - Baris 27–28 (
toSortedlaluconsole.log(angkaAcak)): jalan pintas ES2023 menghasilkan urutan yang sama, dan array asal tetap utuh. - Baris 31–34 (
Array.from("Siti")dan[..."Budi"]): dua cara konversi iterable menghasilkan array huruf yang setara. - Baris 38 (
Array.from({ length: 3 }, (_, i) => \Kursi-${i + 1}`): pembentukan tiga elemen sekaligus pemetaannya; parameter_menandai elemen yang diabaikan, sedangkanimemberi nomor urut.
Section Arrays tuntas di sini. Sepanjang section ini kita sudah memakai object literal untuk data produk dan membaca propertinya lewat titik — kebiasaan yang akan terasa lebih mantap setelah section Objects membongkar object secara menyeluruh: properti, method, dan cara object bekerja di balik layar.
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
array-best-practices.js
Unduh berkas// array-best-practices.js
// Memilih method yang tepat, menyalin sebelum mutasi, mengubah iterable jadi array.
// --- 1. Pilih method sesuai tujuan ---
const stokBuah = ["Apel", "Jeruk", "Mangga", "Jeruk"];
console.log(stokBuah.includes("Jeruk")); // cukup tahu ada atau tidak
console.log(stokBuah.indexOf("Jeruk")); // butuh posisi pertamanya
const semuaPendek = stokBuah.every((buah) => buah.length <= 6);
console.log(semuaPendek);
// --- 2. Salin dulu, baru mutasi: asal tetap utuh ---
const keranjang = ["Buku", "Pulpen"];
const salinanKeranjang = keranjang.slice(); // salinan dangkal (shallow copy)
salinanKeranjang.push("Penghapus");
console.log(salinanKeranjang);
console.log(keranjang);
// Mengurutkan lewat salinan, bukan array asal
const angkaAcak = [30, 10, 20];
const terurut = [...angkaAcak].sort((a, b) => a - b);
console.log(terurut);
console.log(angkaAcak);
// ES2023 menyediakan jalan pintas yang sama: toSorted
console.log(angkaAcak.toSorted((a, b) => a - b));
console.log(angkaAcak);
// --- 3. Mengubah iterable menjadi array ---
const hurufNama = Array.from("Siti");
console.log(hurufNama);
const hurufLain = [..."Budi"];
console.log(hurufLain);
// Argumen kedua Array.from sekaligus memetakan isinya
const nomorKursi = Array.from({ length: 3 }, (_, i) => `Kursi-${i + 1}`);
console.log(nomorKursi);