WeakMap mirip Map: menyimpan pasangan key dan value. Bedanya, key-nya harus object, dan WeakMap gak menahan object itu supaya tetap ada di memori. WeakSet sama, tapi cuma menyimpan object tanpa value. Ibarat label yang ditempel di barang: barangnya dibuang, labelnya ikut hilang.
🧪 Tebakan cepat:
new WeakMap().set('nama', 'Budi')jalan atau error? Tebak dulu, jawabannya ada di bagian "Key harus object".
Menyimpan data milik sebuah object
const cache = new WeakMap()
let user = { nama: 'Budi' }
cache.set(user, 'profil Budi')
console.log(cache.get(user)) // profil Budi
console.log(cache.has(user)) // true
user = null
new WeakMap()bikin WeakMap kosong.cache.set(user, 'profil Budi')menyimpan value'profil Budi'dengan key berupa objectuser.cache.get(user)mengambil value-nya lagi, pakai object yang sama.cache.has(user)menjawabtrueataufalse, dancache.delete(user)menghapus pasangannya.user = nullbikin variabelusergak lagi menunjuk ke object tadi. Sekarang gak ada yang memakai object itu lagi.
JavaScript punya garbage collector: bagian yang membuang object yang sudah gak dipakai siapa pun dari memori. WeakMap gak dihitung sebagai "pemakai", jadi object tadi boleh dibuang, dan datanya di cache ikut hilang. Map biasa beda: Map itu sendiri tetap memegang key-nya, jadi object dan datanya tetap di memori sampai kamu menghapusnya. Kapan pembuangannya terjadi, browser yang menentukan.
Karena isinya bisa hilang kapan saja, WeakMap gak punya size, dan gak bisa diulang dengan for...of.
Menghitung per object
WeakMap cocok buat data tambahan per object, misalnya berapa kali sebuah object dipakai:
const kunjungan = new WeakMap()
const halaman = {}
kunjungan.set(halaman, (kunjungan.get(halaman) || 0) + 1)
kunjungan.set(halaman, (kunjungan.get(halaman) || 0) + 1)
console.log(kunjungan.get(halaman)) // 2
- Pertama kali,
kunjungan.get(halaman)masihundefined, danundefined + 1hasilnyaNaN.|| 0memakai0sebagai nilai cadangan. (... || 0) + 1adalah hitungan baru, dansetmenimpa nilai lama dengan nilai itu.- Dua kali
set, hasilnya2.
Key harus object
const wm = new WeakMap()
wm.set('nama', 'Budi') // TypeError
Jawaban tebakan: error. String kayak 'nama' bisa ditulis ulang kapan saja, jadi gak pernah benar-benar "dibuang", dan WeakMap menolaknya dengan TypeError. Butuh key berupa string atau angka? Pakai Map biasa.
WeakSet: menandai object
const sudahDiproses = new WeakSet()
function proses(obj) {
if (sudahDiproses.has(obj)) {
return 'Sudah diproses!'
}
sudahDiproses.add(obj)
return 'Memproses...'
}
const pesanan = { id: 1 }
console.log(proses(pesanan)) // Memproses...
console.log(proses(pesanan)) // Sudah diproses!
WeakSet cuma punya add, has dan delete. Dia menjawab satu pertanyaan: object ini sudah ditandai atau belum? Sama kayak WeakMap, isinya harus object dan gak menahan object itu di memori.
⚠️ Jebakan yang sering ketemu
- Lupa nilai cadangan.
getuntuk object yang belum punya data memberiundefined, danundefined + 1jadiNaN. Tambah|| 0. - Pakai object baru sebagai key.
wm.get({})selaluundefined, karena{}yang baru adalah object lain. Pakai object yang sama dengan waktuset. - Mencari
sizeataufor...of. Gak ada di WeakMap dan WeakSet. Butuh itu? Pakai Map atau Set.
TL;DR: WeakMap menyimpan data dengan key berupa object: set, get, has, delete. Key-nya harus object (string memberi TypeError), dan WeakMap gak mencegah object itu dibuang garbage collector, jadi datanya ikut hilang saat object-nya gak dipakai lagi. Karena itu gak ada size dan for...of. WeakSet menyimpan object saja, buat menandai: add, has, delete. Buat hitungan, pakai (wm.get(obj) || 0) + 1.