Proxy و Reflect؛ دستکاری رفتار پایهای آبجکتها
خلاصهٔ کاملتر
نویسنده اول یادآوری میکنه که خوندن یه پراپرتی با نقطه یا براکت، خودش نمایندهی همهی مراحل واقعی نیست؛ بلکه فقط APIایه که یه عملیات داخلی به اسم [[Get]] رو راه میندازه و همون عملیات تصمیم میگیره نتیجه چی باشه. ما نمیتونیم مستقیم بریم توی این مراحل دست ببریم — اون قلمرو موتور جاوااسکریپته — ولی میتونیم این عملیاتها رو رهگیری کنیم.
ابزار این کار آبجکت Proxyئه. سازندهی Proxy یه آبجکت میسازه که واسطهی یه آبجکت هدف میشه: تو با پراکسی کار میکنی و اون عملیاتها رو روی هدف اعمال یا بازتعریف میکنه. پراکسی دوتا اسلات داخلی داره، [[Target]] که همون آبجکت هدفه و [[Handler]] که آبجکت واسطهست و رفتار رو تعیین میکنه.
هستهی ماجرا همین هندلره. هر متد هندلر یه trapئه که یه عملیات داخلی رو میگیره. مثلاً متد get سه آرگومان داره: آبجکت هدف، کلید پراپرتیِ درخواستی، و یه «receiver» که مقدار this داخل گتره و معمولاً همون آبجکت هدفه. با همین trap میشه مقدار خروجی رو کامل عوض کرد:
const targetObject = { theProperty: "A string." };
const handlerObject = {
get() {
return "Something else entirely.";
}
};
const theProxyObject = new Proxy(targetObject, handlerObject);
console.log(theProxyObject.theProperty);
// Result: "Something else entirely."نکتهی مهم اینه که هر متد داخلی یه trap متناظر داره، پس عملاً میتونی رفتار پایهای هر آبجکتی، در هر سطحی رو تغییر بدی. نویسنده تأکید میکنه که همینجاست که خط باریکی بین «هیجانانگیز» و «ترسناک» کشیده میشه؛ چون شکستن فرضهایی به بزرگیِ «وقتی یه پراپرتی میسازم همونطور که انتظار دارم کار میکنه» دیر یا زود کدت رو دچار دردسر میکنه.
به همین خاطر استاندارد ES-262 برای عملیاتهایی مثل [[Set]] یه سری invariant تعریف کرده؛ قاعدههایی که trapت باید رعایت کنه، مثل اینکه نتیجهی [[Set]] باید Boolean باشه یا نمیتونی مقدار یه پراپرتیِ non-writable و non-configurable رو عوض کنی. به محض اینکه شروع کنی به دستکاری این عملیاتها، رعایت این قاعدهها دیگه گردن خودته.
اینجاست که Reflect میاد وسط. نویسنده میگه دستکاری [[Get]] با همون سینتکسی که داری تغییرش میدی حس عجیبی داره؛ Reflect یه راه تمیز میده که همون رفتار پیشفرضِ عملیاتهای داخلی رو داخل trapها صدا بزنی و کد قابلاعتمادتر و کمریسکتری بنویسی.
نکات کلیدی:
- دسترسی به پراپرتی فقط APIایه که عملیات داخلی مثل [[Get]] رو راه میندازه؛ Proxy همینها رو رهگیری میکنه.
- هندلر پراکسی برای هر عملیات یه trap داره؛ مثلاً get با آرگومانهای target و key و receiver.
- هر متد داخلی trap متناظر داره، پس رفتار پایهای هر آبجکت قابل بازتعریفه — که هم قدرتمنده هم خطرناک.
- باید invariantهای استاندارد رو رعایت کنی و Reflect برای اجرای تمیزِ رفتار پیشفرض داخل trapها به کارت میاد.




