الميتـا برمجة هي نموذج برمجي قوي يسمح للكود بالتلاعب بسلوكه ديناميكياً أثناء وقت التشغيل. لقد أخذت JavaScript، مع إدخال الوكلاء وAPI Reflect في ES6، قدرات الميتـا برمجة إلى مستوى جديد، مما يمكّن المطورين من اعتراض وإعادة تعريف العمليات الأساسية على الكائنات مثل الوصول إلى الخصائص، والتعيين، واستدعاء الدوال.
تغوص هذه التدوينة في عمق هذه الميزات المتقدمة في JavaScript، موضحةً تركيبها، حالات استخدامها، وكيفية عملها معاً لتمكين البرمجة الديناميكية.
ما هي الوكلاء؟
الـ وكيل في JavaScript هو غلاف يسمح للمطورين باعتراض وتخصيص العمليات الأساسية التي تُجرى على كائن. تشمل هذه العمليات الحصول على الخصائص وتعيينها، واستدعاء الدوال، وحذف الخصائص، والمزيد.
تركيب الوكيل
const proxy = new Proxy(target, handler);
target
: الكائن الذي يتم استخدامه كوكيل.handler
: كائن يحتوي على طرق، تُعرف بالفخاخ، التي تحدد سلوكيات مخصصة للعمليات المعترضة.
مثال: تسجيل الوصول إلى الخصائص
const user = { name: 'Alice', age: 30 };
const proxy = new Proxy(user, {
get(target, property) {
console.log(`Accessing property: ${property}`);
return target[property];
}
});
console.log(proxy.name); // Logs: Accessing property: name → Output: Alice
الفخاخ الرئيسية للوكيل
Trap Name | Operation Intercepted |
---|---|
get |
الوصول إلى خاصية (obj.prop أو obj['prop'] ) |
set |
تعيين قيمة لخاصية (obj.prop = value ) |
deleteProperty |
حذف خاصية (delete obj.prop ) |
يمتلك |
التحقق من وجود الخاصية (prop in obj ) |
تطبيق |
استدعاء الدالة (obj() ) |
إنشاء |
إنشاء مثيلات جديدة باستخدام new (new obj() ) |
حالات استخدام متقدمة مع البروكسيات
1. تحقق من صحة المدخلات
const user = { age: 25 };
const proxy = new Proxy(user, {
set(target, property, value) {
if (property === 'age' && typeof value !== 'number') {
throw new Error('Age must be a number!');
}
target[property] = value;
return true;
}
});
proxy.age = 30; // Works fine
proxy.age = '30'; // Throws Error: Age must be a number!
في هذا المثال، يضمن فخ set
التحقق من النوع قبل السماح بالتعيينات.
2. أنظمة تفاعلية (تشبه تفاعلية Vue.js)
const data = { price: 5, quantity: 2 };
let total = 0;
const proxy = new Proxy(data, {
set(target, property, value) {
target[property] = value;
total = target.price * target.quantity;
console.log(`Total updated: ${total}`);
return true;
}
});
proxy.price = 10; // Logs: Total updated: 20
proxy.quantity = 3; // Logs: Total updated: 30
هذا الكود يعيد حساب القيم ديناميكيًا كلما تم تحديث الخصائص المعتمدة، مما يحاكي سلوك الإطارات التفاعلية الحديثة.
ما هو Reflect؟
تكمل واجهة برمجة التطبيقات Reflect البروكسيات من خلال توفير طرق تؤدي سلوكيات افتراضية لعمليات الكائن، مما يسهل دمجها في فخاخ البروكسي.
الطرق الرئيسية في Reflect
Method | Description |
---|---|
Reflect.get(target, prop) |
يسترجع قيمة خاصية. |
Reflect.set(target, prop, val) |
يحدد قيمة خاصية. |
Reflect.has(target, prop) |
يتحقق من وجود الخاصية (prop in obj ). |
Reflect.deleteProperty(target, prop) |
يحذف خاصية. |
Reflect.apply(func, thisArg, args) |
يتصل بدالة مع سياق this محدد. |
Reflect.construct(target, args) |
ينشئ مثيلًا جديدًا من مُنشئ. |
مثال: استخدام Reflect للسلوك الافتراضي
const user = { age: 25 };
const proxy = new Proxy(user, {
set(target, property, value) {
if (property === 'age' && typeof value !== 'number') {
throw new Error('Age must be a number!');
}
return Reflect.set(target, property, value); // Default behavior
}
});
proxy.age = 28; // Sets successfully
console.log(user.age); // Output: 28
يسهل استخدام Reflect الشيفرة من خلال الحفاظ على العمليات الافتراضية مع إضافة منطق مخصص.
حالات الاستخدام في العالم الحقيقي
- أغلفة الأمان: تقييد الوصول إلى الخصائص الحساسة.
- تسجيل الأخطاء وتصحيحها: تتبع تغييرات الكائنات.
- تحقق من صحة بيانات API: ضمان قواعد صارمة لبيانات API.
الخاتمة
تمكن البرمجة الميتا باستخدام البروكسيات و Reflect المطورين من التحكم ديناميكيًا في سلوك التطبيق وتعديله. اتقن هذه الأدوات لرفع مستوى خبرتك في JavaScript.
تشفير سعيد!
Source:
https://dzone.com/articles/metaprogramming-proxies-reflect-javascript