Proxy: Mengintip dan Mengatur Akses Object
Mengenal new Proxy: membungkus object dengan trap get dan set untuk validasi otomatis, logging, dan nilai default.
Kenapa Proxy Ada
Bayangkan kamu ingin setiap perubahan pada object user otomatis divalidasi: umur tidak boleh negatif, email harus mengandung @. Cara manualnya: menulis setter untuk tiap properti, atau memeriksa manual setiap kali ada assignment. Keduanya melelahkan dan mudah terlewat. Proxy menyelesaikan ini secara elegan: ia membungkus object dan "mencegat" operasi seperti baca (get) dan tulis (set), sehingga kamu bisa menyisipkan logika di tengahnya tanpa mengubah kode yang memakai object tersebut.
Proxy Pertama: Get Trap
const user = { nama: "Rina", umur: 17 };
const userProxy = new Proxy(user, {
get(target, properti) {
console.log("Membaca:", properti);
return target[properti];
}
});
console.log(userProxy.nama);
// "Membaca: nama"
// "Rina"new Proxy(target, handler) menerima object asli dan object handler berisi trap. Trap get dipanggil setiap kali ada yang membaca properti lewat proxy. Perhatikan: kode yang memakai userProxy.nama tidak berubah sama sekali, tapi sekarang ada logging otomatis.
Set Trap: Validasi Otomatis
Inilah kasus penggunaan paling populer: validasi saat assignment.
const akun = { username: "rina", umur: 17 };
const akunAman = new Proxy(akun, {
set(target, properti, nilai) {
if (properti === "umur") {
if (typeof nilai !== "number" || nilai < 0) {
throw new Error("Umur harus angka positif!");
}
}
if (properti === "email" && !nilai.includes("@")) {
throw new Error("Email tidak valid!");
}
target[properti] = nilai; // tulis beneran
return true; // wajib: tandai sukses
}
});
akunAman.umur = 18; // OK
akunAman.umur = -5; // Error: Umur harus angka positif!
akunAman.email = "salah"; // Error: Email tidak valid!Validasi terjadi di SATU tempat, tidak peduli dari berapa banyak bagian kode assignment itu datang. Ini jauh lebih aman daripada berharap setiap programmer ingat memeriksa manual.
Nilai Default dengan Get
Trap get juga bisa menyediakan nilai cadangan saat properti tidak ada:
const pengaturan = new Proxy({}, {
get(target, properti) {
return properti in target ? target[properti] : "default";
}
});
pengaturan.tema = "gelap";
console.log(pengaturan.tema); // "gelap"
console.log(pengaturan.bahasa); // "default" (tidak error undefined)Pola ini dipakai pustaka konfigurasi: pengguna hanya mengisi yang perlu, sisanya otomatis terisi default.
Contoh Nyata: Proteksi Object
// cegah properti baru yang tidak dikenal (typo!)
const profil = new Proxy({ nama: "", umur: 0 }, {
set(target, properti, nilai) {
if (!(properti in target)) {
throw new Error("Properti tidak dikenal: " + properti);
}
target[properti] = nilai;
return true;
}
});
profil.nama = "Budi"; // OK
profil.namma = "X"; // Error! Typo tertangkap langsungTypo nama properti adalah bug yang diam-diam membuat properti baru berisi undefined. Dengan proxy, typo langsung meledak menjadi error yang jelas.
Jebakan Umum
Pertama, trap set WAJIB mengembalikan true; kalau tidak, assignment gagal diam-diam (atau melempar TypeError di strict mode). Kedua, proxy hanya bekerja jika semua kode memakai object proxy-nya, bukan object aslinya: kalau ada yang masih memegang referensi akun langsung, validasi bisa dilewati. Ketiga, jangan over-engineering: untuk satu-dua validasi sederhana, if biasa lebih mudah dibaca daripada proxy.
Catatan teknis: Proxy adalah metaprogramming: program yang mengatur perilaku program. Selain get/set ada trap lain seperti
has(operator in),deleteProperty(delete), danapply(untuk fungsi). Framework reaktif seperti Vue 3 memakai Proxy sebagai fondasi sistem reaktivitasnya: setiap perubahan data otomatis memicu render ulang, persis seperti validasi otomatis di atas tapi untuk UI.
export default function App(): JSX.Element { return <h1>Hello world</h1> }
Tantangan
Dompet Digital Tervalidasi
Aplikasi keuangan nyata tidak boleh membiarkan saldo menjadi negatif atau menerima jumlah bukan angka: satu data rusak bisa merambat ke laporan dan transaksi. Tantanganmu: bungkus object dompet = { saldo: 100000 } dengan Proxy yang menolak (throw Error) setiap assignment saldo yang bukan number positif, tapi tetap mengizinkan baca dan tulis yang valid. Uji dengan assignment benar, negatif, dan string.
<!doctype html> <html> <head> <meta charset="utf-8" /> </head> <body> <h1>Halo JS</h1> <p>Buka console preview untuk melihat output.</p> <script src="index.js"></script> </body> </html>