המטה-תכנות היא פרדיגמה תכנותית עוצמתית שמאפשרת לקוד לנהל את התנהגותו באופן דינמי בזמן ריצה. JavaScript, עם הכנסת Proxies ו-API Reflect ב-ES6, הביא את יכולות המטה-תכנות לרמה חדשה, מאפשר למפתחים להתערב ולהגדיר מחדש פעולות עיקריות של אובייקטים כגון גישה לתכונות, השמה, וקריאת פונקציות.
פוסט הבלוג הזה חוקר בעומק את תכונות JavaScript מתקדמות אלו, מבאר את התחביר שלהן, מציין מקרי שימוש, ואיך הן עובדות יחד כדי להעצים תכנות דינמי.
מהם Proxies?
Proxy ב-JavaScript הוא מעטפת שמאפשרת למפתחים להתערב ולהתאים פעולות יסודיות שמתבצעות על אובייקט. הפעולות אלו כוללות קבלה והצבה של תכונות, קריאות לפונקציות, מחיקת תכונות, ועוד.
תחביר של Proxy
const proxy = new Proxy(target, handler);
target
: האובייקט שמחולל פרוקסי.handler
: אובייקט המכיל שיטות, ידועות גם כ-traps, שמגדירות התנהגויות מותאמות אישית עבור הפעולות שנתפסו.
דוגמה: רישום גישה לתכונה
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
פלטי Proxy המרכזיים
Trap Name | Operation Intercepted |
---|---|
get |
גישה לתכונה (obj.prop או obj['prop'] ) |
set |
השמה של ערך לתכונה (obj.prop = value ) |
deleteProperty |
מחיקת נכס (delete obj.prop ) |
has |
בדיקת קיום נכס (prop in obj ) |
apply |
קריאת פונקציה (obj() ) |
construct |
יצירת מופעים חדשים עם new (new obj() ) |
מקרים מתקדמים עם Proxies
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
trap מבצע אימות סוג לפני אישור השמות.
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 משלים את Proxies על ידי ספק מתודות שמבצעות התנהגויות ברירת מחדל עבור פעולות אובייקט, מה שהופך את השילוב שלהם עם Proxy traps לפשוט יותר.
מתודות 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