مقدمه

Proxy (پراکسی) یکی از قابلیت‌های پیشرفته جاوااسکریپت است که امکان کنترل و تغییر رفتار پیش‌فرض اشیا را فراهم می‌کند. با استفاده از پراکسی می‌توانید رفتار خواندن، نوشتن، حذف و حتی فراخوانی متدها را شخصی‌سازی کنید و روی دسترسی به شیء، "ناظر" قرار دهید. پراکسی در اعتبارسنجی داده، لاگ‌گیری، ساخت APIهای دینامیک، حفاظت از داده و حتی ساخت فریم‌ورک‌ها استفاده می‌شود و ابزاری قدرتمند برای توسعه حرفه‌ای محسوب می‌شود.

ساختار و سینتکس Proxy

برای ساخت یک پراکسی باید دو چیز را تعیین کنید: شیء هدف (target) که می‌خواهید رفتار آن را کنترل کنید، و شیء handler که مجموعه‌ای از Trapها (توابع کنترل‌کننده عملیات) را تعریف می‌کند.

مثال زیر یک پراکسی ساده برای شیء user می‌سازد.

Copy Icon JAVASCRIPT
let user = { name: "ali" };
let proxy = new Proxy(user, {
  get(target, prop) {
    console.log("Read:", prop);
    return target[prop];
  }
});
console.log(proxy.name); // Read: name  → ali

در این مثال، هر بار که پراپرتی از شیء proxy خوانده شود، پیام "Read:" همراه با نام پراپرتی در کنسول چاپ می‌شود. این یعنی می‌توانید روی عملیات خواندن پراپرتی‌ها نظارت کنید یا رفتار آن را تغییر دهید.

متدهای Trap در Proxy

Trapها متدهایی در handler هستند که هر بار عملیاتی مثل get، set، deleteProperty، has و ... روی شیء هدف انجام شود، اجرا می‌شوند و می‌توانند رفتار پیش‌فرض را تغییر دهند یا مانع عملیات شوند. در مثال بالا get هر بار که پراپرتی‌ای از شیء پراکسی خوانده شود اجرا می‌شود و می‌توانید رفتار خواندن را تغییر دهید. Trapهای دیگری مثل set برای نوشتن، deleteProperty برای حذف و has برای عملگر in نیز وجود دارند که هرکدام اجازه می‌دهند عملیات مربوطه را کنترل یا شخصی‌سازی کنید.

انواع Trap و کاربردهای آنها

همانطور که گفته شد، یک Trap متدی است که هنگام انجام عملیات خاصی روی شیء هدف (مثل خواندن، نوشتن یا حذف پراپرتی) اجرا می‌شود و می‌تواند رفتار پیش‌فرض را تغییر دهد یا کنترل کند. هر Trap بسته به نوع عملیات، پارامترهای متفاوتی دریافت می‌کند و می‌توانید با استفاده از آن‌ها منطق دلخواه خود را پیاده‌سازی کنید. مهم‌ترین trapها در پراکسی: get (خواندن پراپرتی)، set (نوشتن پراپرتی)، deleteProperty (حذف پراپرتی)، has (بررسی in)، ownKeys (دریافت کلیدها)، apply (فراخوانی تابع) و construct (ایجاد نمونه جدید) هستند.

استفاده از get و set برای اعتبارسنجی

یکی از مهمترین کاربردهای Trapهای get و set اعتبارسنجی داده‌هاست. فرض کنید می‌خواهید فقط مقادیر عددی در یک شی ذخیره شوند؛ با استفاده از پراکسی می‌توانید این محدودیت را به راحتی اعمال کنید. این مثال مقدار عددی را کنترل می‌کند و اگر مقدار نامعتبر باشد خطا می‌دهد:

Copy Icon JAVASCRIPT
let numbers = {};
let proxy = new Proxy(numbers, {
  set(target, prop, value) {
    if (typeof value !== "number") {
      throw new TypeError("Only numeral value is valid");
    }
    target[prop] = value;
    return true;
  }
});
proxy.score = 10;
proxy.score = "Hello"; // Error

در اینجا اگر مقدار غیرعددی به پراپرتی‌های شیء proxy اختصاص دهید، خطای TypeError رخ می‌دهد و مقدار ذخیره نمی‌شود. این روش برای اعتبارسنجی داده‌ها و جلوگیری از ورود داده‌های نامعتبر بسیار کاربردی است.

استفاتده از apply برای کنترل توابع

apply یک Trap پرکاربرد دیگر است که می‌توانیم با استفاده از آن، فراخوانی توابع را کنترل یا لاگ‌‌گیری کنسم. به مثال زیر توجه کنید.

Copy Icon JAVASCRIPT
function sum(a, b) { return a + b; }
let proxySum = new Proxy(sum, {
  apply(target, thisArg, args) {
    console.log("function is called");
    return target.apply(thisArg, args);
  }
});

proxySum(1, 2); // function is called

Proxy ابزاری بسیار قدرتمند برای کنترل و شخصی‌سازی رفتار اشیا و توابع در جاوااسکریپت است. با آن می‌توانید APIهای دینامیک، لایه‌های امنیتی یا ابزارهای حرفه‌ای بسازید.

در استفاده از پراکسی دقت کنید که برخی فریم‌ورک‌ها (مثل Vue.js) برای reactivity و مدیریت state، به شدت از این قابلیت بهره می‌برند. پس آشنایی عملی با Proxy مسیر توسعه حرفه‌ای را برای شما باز می‌کند.