WeakMap & WeakSet — JavaScript

Coba bayangin label sticker kecil yang kamu tempel di belakang TV: "garansi sampai 2027". Pas TV-nya kamu buang, label otomatis ikut hilang — gak ada record…

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

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

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

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.

Yang akan kamu pelajari