مقدمه

Reflect یک شیء داخلی جدید در جاوااسکریپت است که مجموعه‌ای از متدهای استاتیک برای عملیات سطح پایین روی اشیا و پراپرتی‌ها را ارائه می‌دهد. متدهای Reflect اساساً همان عملیات استاندارد object را به شیوه‌ای امن‌تر و قابل پیش‌بینی‌تر انجام می‌دهند و در توسعه پراکسی‌ها کاربرد زیادی دارند. متدهای Reflect شبیه به متدهای Object هستند اما رفتار یکسان با trapهای Proxy دارند (خطاها را return می‌کنند، نه throw). Reflect همیشه رفتار استاندارد را حفظ می‌کند و نوشتن Proxyهای تمیز و حرفه‌ای را آسان‌تر می‌کند.

متدهای مهم Reflect

در این بخش با مهم‌ترین متدهای Reflect آشنا می‌شوید که برای خواندن، نوشتن، حذف و بررسی وجود پراپرتی‌ها و همچنین کار با کلیدهای شیء و فراخوانی توابع به کار می‌روند. این متدها جایگزین مناسبی برای عملگرهای سنتی هستند و رفتار استاندارد و قابل پیش‌بینی ارائه می‌دهند.

متدهای Reflect.get و Reflect.set

Reflect.get برای خواندن مقدار یک پراپرتی از شیء و Reflect.set برای مقداردهی یا اضافه کردن پراپرتی جدید استفاده می‌شود. این متدها مشابه دسترسی مستقیم (obj.prop یا obj["prop"]) عمل می‌کنند اما در هندلرهای پراکسی و سناریوهای پیشرفته، کنترل بیشتری فراهم می‌کنند.

Copy Icon JAVASCRIPT
let obj = { a: 1 };
console.log(Reflect.get(obj, "a")); // 1
Reflect.set(obj, "b", 2);
console.log(obj.b); // 2

در اینجا اگر پراپرتی مورد نظر وجود نداشته باشد، Reflect.get مقدار undefined برمی‌گرداند و Reflect.set پراپرتی جدید را اضافه می‌کند. این متدها در نوشتن پراکسی بسیار کاربردی هستند.

متدهای Reflect.has و Reflect.deleteProperty

Reflect.has مانند عملگر in و Reflect.deleteProperty معادل delete است اما رفتار استاندارد و امن‌تری دارند. مصال زیر را ببینید.

Copy Icon JAVASCRIPT
console.log(Reflect.has(obj, "a")); // true
Reflect.deleteProperty(obj, "a");
console.log(obj); // { b: 2 }

در اینجا Reflect.has بررسی می‌کند که آیا پراپرتی مورد نظر در شیء وجود دارد یا نه (مانند عملگر in) و Reflect.deleteProperty پراپرتی را به صورت استاندارد و بدون خطا حذف می‌کند. این متدها مخصوصاً در سناریوهایی که با پراکسی کار می‌کنید، رفتار قابل پیش‌بینی‌تری نسبت به روش‌های سنتی دارند.

سایر متدهای Reflect

متدهای دیگری هم در Reflect وجود دارند که برای کار با اشیا و توابع بسیار مفید هستند:

  • Reflect.ownKeys(obj): همه کلیدهای شیء (شامل Symbolها) را به صورت آرایه برمی‌گرداند.
  • Reflect.defineProperty(obj, prop, desc): مشابه Object.defineProperty، پراپرتی جدید با ویژگی‌های دلخواه تعریف می‌کند.
  • Reflect.getOwnPropertyDescriptor(obj, prop): ویژگی‌های یک پراپرتی را برمی‌گرداند.
  • Reflect.preventExtensions(obj): از افزودن پراپرتی جدید به شیء جلوگیری می‌کند.
  • Reflect.isExtensible(obj): بررسی می‌کند آیا شیء قابل توسعه است یا نه.
  • Reflect.apply(func, thisArg, args): یک تابع را با this و آرگومان‌های دلخواه فراخوانی می‌کند.
  • Reflect.construct(constructor, args): مشابه new، یک شیء جدید می‌سازد.

این متدها باعث می‌شوند کنترل کامل و استاندارد روی اشیا و توابع داشته باشید و کدهای پیشرفته‌تری بنویسید.

Reflect و Proxy در کنار هم

اصلی‌ترین کاربرد Reflect در نوشتن هندلرهای پراکسی است؛ چون می‌توانید عملیات پیش‌فرض را به سادگی و به شکل استاندارد انجام دهید و کد شما خوانا و قابل پیش‌بینی باقی بماند.

توصیه حرفه‌ای این است که در هندلرهای پراکسی به جای دستکاری مستقیم target، از متدهای Reflect استفاده کنید. مثال زیر را ببینید.

Copy Icon JAVASCRIPT
let user = { name: "lale" };
let proxy = new Proxy(user, {
  get(target, prop, receiver) {
    return Reflect.get(target, prop, receiver);
  },
  set(target, prop, value, receiver) {
    return Reflect.set(target, prop, value, receiver);
  }
});
proxy.name = "negar";
console.log(proxy.name); // negar

در این مثال، متدهای Reflect.get و Reflect.set در هندلرهای پراکسی استفاده شده‌اند تا عملیات پیش‌فرض خواندن و نوشتن پراپرتی‌ها به صورت استاندارد انجام شود. این کار باعث می‌شود اگر در آینده رفتار پیش‌فرض جاوااسکریپت تغییر کند یا پراکسی پیچیده‌تر شود، کد شما همچنان قابل اطمینان و قابل نگهداری باقی بماند. همچنین، Reflect خطاها را به صورت مقدار بازمی‌گرداند و throw نمی‌کند که مدیریت آن را ساده‌تر می‌کند.