متدهای مخفی در جاوااسکریپت با Proxy
خلاصهٔ کاملتر
نویسنده با یه معما شروع میکنه: یه آبجکت به اسم obj داری که تو console.log فقط متد hello رو نشون میده، ولی obj.goodbye() هم کار میکنه. goodbye نه تو Object.keys(obj) دیده میشه، نه تو Reflect.ownKeys(obj)، نه تو حلقهٔ for...in و نه حتی وقتی تو DevTools مرورگر بررسیش کنی.
جواب معما Proxy هست (یعنی یه لایه دور آبجکت که کارهای روی اون رو رهگیری میکنه). با Proxy میشه تقریباً هر عملیاتی رو "trap" کرد: خوندن پراپرتی، مقداردهی، شمردن کلیدها و حتی حذف پراپرتی. نویسنده میگه Proxy مثل یه hook یا middleware عمل میکنه و میتونه آبجکت رو هر جوری بخوای به صدازننده نشون بده. کد اصلی معما اینه:
const publicObject = { hello: privateObj.hello };
return new Proxy(publicObject, {
get(target, property, receiver) {
if (property === "goodbye") return privateObj.goodbye;
return Reflect.get(target, property, receiver);
},
});یعنی آبجکت واقعی فقط hello رو داره، ولی trap مربوط به get وقتی کسی goodbye رو بخواد، اونو از یه آبجکت خصوصی برمیگردونه. یه مثال دیگه تو مقاله یه آبجکت "نفرینشده" هست که trap مربوط به set نمیذاره isEnabled هیچوقت true بشه، در حالی که counter عادی زیاد میشه.
نویسنده Proxy رو موقع ساخت بازی Pragma Twice پیدا کرده، یه بازی پازل جاوااسکریپتی که هر آبجکتش یه API داره. اون میخواست بعضی متدها تا وقتی بازیکن کشفشون نکرده مخفی بمونن، ولی بازیکن باتجربهای که اسمشون رو میدونه بتونه از اول ازشون استفاده کنه. الهامش هم بازی Tunic بوده که توش چیزی که باز میکنی "دانش" هست.
کاربردهای جدیتر هم داره: مثلاً میشه console سراسری رو با یه Proxy عوض کرد که لاگها رو همزمان به کنسول و یه فایل بفرسته. فریمورکهای واکنشی مثل Vue هم از Proxy استفاده میکنن تا تغییر آبجکتها رو خودکار بفهمن و UI رو آپدیت کنن. برای پیدا کردن پراپرتیهای مخفی هم نویسنده میگه فقط حدس زدن با typeof obj[guess] و یه لیست کلمه یا brute force به ذهنش میرسه.
نکات کلیدی:
- Proxy میتونه خوندن، نوشتن، شمردن و حذف پراپرتیها رو رهگیری کنه.
- پراپرتیای که فقط تو trap مربوط به get برگردونده بشه، تو Object.keys، Reflect.ownKeys و console.log دیده نمیشه.
- سیستم واکنشی Vue روی Proxy ساخته شده.
- تنها راه کشف پراپرتی مخفی بدون دیدن سورس، حدس زدن با typeof obj[guess] هست.




