Proxy & Reflect — JavaScript

Bayangin sekretaris pribadi yang nyaring semua telepon masuk dan keluar buat bos. Setiap kali ada yang nelepon → sekretaris cek dulu, log, baru sambungin…

Proxy adalah pembungkus object yang menangkap tiap operasi ke object itu, misalnya membaca atau mengubah properti, sebelum operasinya sampai ke object aslinya. Di situ kamu bisa mencatat, mengecek, lalu meneruskan atau menolak. Mirip satpam di depan pintu: semua yang masuk lewat dia dulu.

🧪 Tebakan cepat: object { nama: 'Budi' } gak punya properti umur. Apakah membaca umur lewat Proxy pasti menghasilkan undefined? Tebak dulu, jawabannya ada di bagian "Trap get: menangkap pembacaan".

Proxy pertama: trap set buat validasi

const target = { umur: 20 }

const siswa = new Proxy(target, {
  set(obj, prop, value) {
    if (typeof value !== 'number' || value <= 0) {
      throw new Error('Umur harus angka lebih dari 0')
    }
    obj[prop] = value
    return true
  }
})

siswa.umur = 25 // tersimpan
siswa.umur = -5 // Error: Umur harus angka lebih dari 0

Hasilnya, siswa.umur jadi 25, sedangkan -5 ditolak dengan Error dan umurnya tetap 25. siswa.umur = 'abc' juga ditolak, karena tipenya bukan number. Satu catatan: Proxy cuma menjaga operasi yang lewat dia. target.umur = -5, langsung ke object aslinya, gak dicek sama sekali.

Trap get: menangkap pembacaan

const p = new Proxy({ nama: 'Budi' }, {
  get(obj, prop) {
    return prop in obj ? obj[prop] : 'tidak ada'
  }
})

console.log(p.nama) // Budi
console.log(p.umur) // tidak ada

Jawaban tebakan: gak pasti. Tanpa Proxy, p.umur memang undefined. Dengan trap ini, hasilnya 'tidak ada', karena trap yang memutuskan.

Reflect: meneruskan operasi apa adanya

Reflect berisi method dengan nama yang sama dengan trap, dan tiap method melakukan operasi bawaannya:

const handler = {
  get(obj, prop) {
    console.log(`Membaca ${prop}`)
    return Reflect.get(obj, prop)
  },
  set(obj, prop, value) {
    console.log(`Menulis ${prop} = ${value}`)
    return Reflect.set(obj, prop, value)
  }
}

const user = new Proxy({}, handler)
user.nama = 'Budi'     // Menulis nama = Budi
console.log(user.nama) // Membaca nama, lalu Budi

Selain get dan set, ada trap lain kayak has (untuk in) dan deleteProperty (untuk delete).

⚠️ Jebakan yang sering ketemu

TL;DR: new Proxy(target, handler) membungkus object, dan trap di handler menangkap operasinya. Trap set(obj, prop, value) menangkap penulisan: tolak dengan throw new Error(...), atau simpan dengan obj[prop] = value lalu return true. Trap get(obj, prop) menangkap pembacaan, dan yang di-return-nya jadi hasilnya. Reflect.get dan Reflect.set menjalankan operasi bawaannya, jadi trap bisa meneruskan dengan return Reflect.set(obj, prop, value).

Yang akan kamu pelajari