Bayangin sekretaris pribadi yang nyaring semua telepon masuk dan keluar buat bos. Setiap kali ada yang nelepon → sekretaris cek dulu, log, baru sambungin (atau tolak). Setiap kali bos mau nelepon keluar → sekretaris yang dial, mungkin nge-log, mungkin filter dulu. Bos tetap kerja seperti biasa, gak sadar ada filtering. Itu Proxy dalam JavaScript: kamu bungkus object pake "lapisan kontrol", semua operasi (baca, tulis, hapus) lewat trap dulu — kamu bisa logging, validasi, transformasi, sebelum operasi beneran terjadi.
🤔 Pondasi reactive framework. Vue 3 dan Solid pake Proxy buat reactivity system mereka — pas kamu ubah property object, framework otomatis tau dan re-render UI yang related. Kekuatan ini yang bikin developer experience modern terasa "magic" — di balik layar cuma Proxy yang kerja keras.
const handler = {
get(target, prop) {
console.log(`Membaca ${prop}`);
return Reflect.get(target, prop);
},
set(target, prop, value) {
console.log(`Menulis ${prop} = ${value}`);
return Reflect.set(target, prop, value);
}
};
const user = new Proxy({}, handler);
user.nama = "Budi"; // log: Menulis nama = Budi
console.log(user.nama); // log: Membaca nama → "Budi"
Handler Traps yang umum:
get(target, prop)— saat membaca propertyset(target, prop, value)— saat menulis propertyhas(target, prop)— saatinoperator digunakandeleteProperty(target, prop)— saatdeletedigunakan
Reflect API:
Reflect menyediakan method yang sama dengan trap Proxy — memudahkan memanggil perilaku default:
Reflect.get(obj, "nama"); // sama dengan obj.nama
Reflect.set(obj, "nama", "X"); // sama dengan obj.nama = "X"
Reflect.has(obj, "nama"); // sama dengan "nama" in obj
Contoh praktis — validasi:
function buatValidator(obj) {
return new Proxy(obj, {
set(target, prop, value) {
if (typeof value !== "number" || value <= 0) {
throw new Error("Hanya angka positif!");
}
return Reflect.set(target, prop, value);
}
});
}
Use case: validasi data, logging, reactive systems (Vue 3 pakai Proxy!), access control.
🎭 Analogi sehari-hari
Proxy = sekretaris pribadi yang saring semua telepon masuk/keluar untuk bos:
- Get trap = "ada yang nanya nomor bos? log dulu, baru kasih."
- Set trap = "mau tinggalin pesan? cek validasi dulu, baru tulis."
- Has trap = "tanyain bos punya jadwal gak? sekretaris yang jawab."
Object asli (target) tetap ada di belakang. Proxy = lapisan kontrol di depan.
⚠️ Jebakan yang sering ditemui
- Proxy bukan object original.
proxy === target=false. Tidak interchangeable. - Trap harus return value yang benar.
setharus returntrue(sukses) ataufalse(gagal). Di strict mode, false = TypeError. - Proxy + built-in tidak selalu cocok —
Map,Set,Datemethods pakai internal slot, kena masalahthis. PakaiReflect.get(target, prop, receiver)untuk forward. - Performance overhead — setiap akses property lewat trap = cost. Untuk hot path / loop besar, pikir ulang.
- Tidak bisa proxy primitive (string, number) — cuma object.
instanceofmasih jalan via proxy kalau prototype chain target intact.- Reflect bukan global object utility — pasangan logis untuk Proxy. Setiap trap punya counterpart
Reflect.methoddengan signature sama.
TL;DR: Proxy = bungkus object pakai "lapisan kontrol", semua operasi (get/set/has/delete) lewat trap dulu. Use case: validasi, logging, reactive (Vue 3 pakai Proxy!), access control. Reflect = pasangan logis Proxy, panggil perilaku default (Reflect.get(target, prop) = target[prop]). set trap WAJIB return true/false. Performance overhead per akses — hindari di hot path. Cuma works di object (bukan primitive). proxy === target = false.