Menu

Map dan Set JavaScript: Kapan Memakainya daripada Objek dan Array

Cara kerja Map dan Set di JavaScript, perbedaannya dengan objek dan array biasa, dan kapan memakainya benar-benar menguntungkan.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Dua Koleksi di Luar Objek dan Array

Objek dan array biasa sudah mencakup sebagian besar kebutuhan program JavaScript, tetapi keduanya tidak dirancang untuk setiap tugas. Map dan Set adalah koleksi bawaan yang mengisi dua celah tertentu: pencarian berdasarkan key yang bukan string, dan pengecekan keanggotaan tanpa duplikat.

Keduanya sudah ada di bahasa ini sejak ES2015. Keduanya iterable, keduanya punya property .size, dan keduanya cocok dipakai dengan operator spread. Model mentalnya sederhana:

  • Map: seperti objek, tetapi key-nya bisa apa saja dan urutannya dipertahankan.
  • Set: seperti array, tetapi nilainya unik dan pencariannya cepat.

Membuat dan Memakai Map

Map menyimpan pasangan key/value. Kamu membuatnya dengan new Map() lalu memakai .set(), .get(), .has(), dan .delete():

Kamu juga bisa memberikan array berisi pasangan [key, value] ke constructor untuk mengisinya sejak awal:

Bentuk array berisi dua elemen itu muncul di mana-mana saat berurusan dengan Map, karena begitulah entri ditampilkan saat kamu melakukan iterasi.

Map vs Objek: Buat Apa Repot?

Objek biasa terlihat bisa melakukan tugas yang sama. Sebagian besar waktu memang bisa. Tetapi Map memperbaiki beberapa kekurangan tertentu:

Objek mewarisi dari Object.prototype, jadi key seperti toString, constructor, dan hasOwnProperty sudah ada di setiap objek. Map tidak membawa beban seperti itu: key yang kamu isi adalah satu-satunya key yang ada.

Perbedaan lain yang perlu diketahui:

  • Tipe key apa pun. Map menerima objek, fungsi, angka, dan boolean sebagai key. Objek diam-diam mengubah key yang bukan string menjadi string: obj[1] dan obj["1"] adalah slot yang sama.
  • Urutan penambahan yang terjamin. Map melakukan iterasi sesuai urutan entri ditambahkan. Objek sebagian besar juga begitu, tetapi key string yang mirip angka diurutkan lebih dulu, jebakan yang halus.
  • Ukuran bawaan. map.size bernilai O(1). Untuk objek, kamu harus menulis Object.keys(obj).length, yang membangun ulang sebuah array.
  • Dioptimalkan untuk perubahan. Engine mengoptimalkan Map untuk penambahan dan penghapusan yang sering. Objek dioptimalkan untuk record dengan bentuk yang stabil.

Pakai objek saat kamu memodelkan sebuah record dengan key string yang sudah diketahui ({ name, email, age }). Pakai Map saat key-nya dinamis, bukan string, atau saat kamu akan sering menambah dan menghapus entri.

Iterasi pada Map

Map itu iterable, artinya for...of langsung berfungsi dan destructuring setiap entri terasa alami:

Kalau kamu hanya butuh key-nya atau hanya nilainya, panggil .keys() atau .values(). Dan .forEach() juga ada kalau kamu lebih suka:

Untuk mengubah Map kembali menjadi objek atau array biasa, spread saja:

Membuat dan Memakai Set

Set menyimpan nilai unik. Menambahkan nilai yang sudah ada tidak berpengaruh apa-apa:

Keunikan ditentukan dengan aturan kesamaan yang sama seperti ===, dengan satu keanehan: NaN dianggap sama dengan dirinya sendiri di dalam Set, padahal NaN === NaN bernilai false di tempat lain.

Berikan sebuah iterable ke constructor untuk mengisi Set sejak awal. Dari sinilah trik menghapus duplikat berasal:

Satu baris, untuk tipe primitif apa pun. Untuk array berisi objek ini tidak berfungsi, karena dua objek berbeda dengan field yang sama tetaplah dua nilai berbeda, tetapi untuk string, angka, dan boolean, inilah cara yang lazim untuk menghapus duplikat.

Set vs Array: Kapan Beralih

Array dan Set sama-sama menyimpan kumpulan nilai, jadi kapan kamu memilih yang mana?

Pakai Set saat:

  • Nilainya harus unik dan kamu ingin runtime yang memastikannya.
  • Kamu sering melakukan pengecekan keanggotaan. set.has(x) bernilai O(1); array.includes(x) bernilai O(n). Di dalam loop, perbedaan itu cepat sekali berlipat.
  • Urutan penambahan sudah cukup. Set melakukan iterasi sesuai urutan penambahan, tetapi tidak mendukung akses dengan index.

Tetap pakai array saat:

  • Kamu butuh akses berdasarkan posisi: arr[0], slicing, sorting.
  • Duplikat itu bermakna: keranjang belanja dengan dua barang yang sama.
  • Kamu akan banyak memakai method array seperti .map, .filter, .reduce. Set tidak punya method itu; kamu harus melakukan spread ke array dulu.

Contoh singkat yang berkaitan dengan performa:

Kalau banned berupa array, setiap callback filter akan memindai seluruh daftar. Sebagai Set, setiap pencarian butuh waktu konstan.

Iterasi pada Set

Sama seperti Map: for...of langsung berfungsi, dan spread memberimu array:

Set juga menyediakan .keys(), .values(), dan .entries() agar simetris dengan Map, walaupun untuk Set key dan nilainya adalah hal yang sama. Sebagian besar waktu kamu cukup melakukan iterasi langsung.

Contoh Lengkap: Menghitung Pengunjung Unik per Halaman

Menggabungkan keduanya: sebuah Map dari path halaman ke sebuah Set berisi ID pengunjung:

Map menangani pemetaan dari path ke wadahnya; Set menangani penghapusan duplikat di dalam setiap wadah. Melakukan hal yang sama dengan objek biasa dan array memang bisa, tetapi kamu harus menulis pengecekan indexOf dan pengaman hasOwnProperty tambahan di sepanjang jalan.

Sekilas tentang WeakMap dan WeakSet

Ada dua koleksi terkait untuk kasus penggunaan yang sempit: WeakMap dan WeakSet. Keduanya memegang referensi secara lemah, artinya entri yang key-nya (untuk WeakMap) atau nilainya (untuk WeakSet) tidak punya referensi lain akan otomatis dibersihkan oleh garbage collector.

Keduanya hanya menerima objek sebagai key, tidak iterable, dan tidak punya .size. Itu memang disengaja: kalau kamu bisa melakukan iterasi pada keduanya, kerja garbage collector jadi bisa diamati. Keduanya berguna untuk menyimpan cache metadata tentang objek yang bukan milikmu, dan jarang ditemui dalam kode sehari-hari.

Berikutnya: JSON

Map dan Set sangat bagus di memori, tetapi keduanya tidak selamat utuh melewati JSON.stringify: Map menjadi {} dan Set juga menjadi {}. Halaman berikutnya membahas JSON: cara melakukan serialisasi dan parsing data, serta pola untuk menangani koleksi yang diperkenalkan di halaman ini saat harus melintasi jaringan atau batas file.

Pertanyaan yang sering diajukan

Apa bedanya Map dan Object di JavaScript?

Map bisa memakai nilai apa pun sebagai key, seperti objek, fungsi, angka, apa saja, sedangkan objek mengubah key menjadi string (atau symbol). Map juga mencatat ukurannya dengan .size, melakukan iterasi sesuai urutan penambahan, dan tidak mewarisi key dari prototype, jadi tidak ada risiko bentrok dengan toString atau constructor. Pakai Map saat key-nya bukan string atau saat kamu sering menambah dan menghapus entri.

Untuk apa Set dipakai di JavaScript?

Set menyimpan nilai unik: duplikat diabaikan diam-diam. Cara tercepat menghapus duplikat dari array adalah [...new Set(arr)]. Set juga memberimu pengecekan .has() O(1), yang mengalahkan array.includes() saat kamu menguji keanggotaan di dalam loop.

Bagaimana cara melakukan iterasi pada Map?

for...of langsung berfungsi: for (const [key, value] of myMap) melakukan destructuring pada setiap entri. Kamu juga bisa melakukan perulangan pada myMap.keys(), myMap.values(), atau myMap.entries(). Urutan iterasinya dijamin sama dengan urutan penambahan, sesuatu yang tidak selalu dijanjikan objek biasa untuk key yang mirip angka.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai