דקורטורים ב-TypeScript
מאמר זה מסביר את הדקורטורים ב-TypeScript.
YouTube Video
דקורטורים ב-TypeScript
דקורטורים ב-TypeScript הם מנגנון להוספת פונקציונליות או התנהגות נוספת למחלקות, שיטות, גישות, מאפיינים או פרמטרים. דקורטורים הם כלי עוצמתי לשיפור קריאות הקוד ושימוש חוזר בו.
יסודות הדקורטורים
דקורטור הוא פונקציה שמזריקה פונקציונליות נוספת למחלקה או לחברי מחלקה. דקורטורים הוצגו לראשונה ב-TypeScript גרסה 1.5 והוצעו גם לסטנדרט של ECMAScript.
1{
2 "compilerOptions": {
3 "experimentalDecorators": true
4 }
5}
- כדי להשתמש בדקורטורים, עליך לאפשר את האפשרות
experimentalDecorators
בקובץtsconfig.json
.
סוגי דקורטורים
ב-TypeScript ניתן להשתמש בחמשת הסוגים הבאים של דקורטורים.
- דקורטור של מחלקה דקורטור שמיושם למחלקה.
- דקורטור של מתודה דקורטור שמיושם למתודה של מחלקה.
- דקורטור של מאפיין גישה דקורטור שמיושם ל-getter או setter של מאפיין של מחלקה.
- דקורטור של מאפיין דקורטור שמיושם למאפיין של מחלקה.
- דקורטור של פרמטר דקורטור שמיושם לפרמטר של מתודה.
דקורטור של מחלקה
דקורטורים של מחלקה הם דקורטורים המוחלים על מחלקות. דקורטורים של מחלקה נכתבים ממש מעל הגדרת המחלקה ויכולים לגשת לבנאי המחלקה. הם משמשים בעיקר לשינוי התנהגות מחלקה או להוספת מטא-נתונים.
1function Logger(constructor: Function) {
2 console.log(`Class ${constructor.name} is being constructed`);
3}
4
5@Logger
6class Person {
7 constructor(public name: string) {}
8}
9
10const person = new Person('John');
11// Output: Class Person is being constructed
בדוגמה זו, הדקורטור Logger
מוחל על המחלקה, והודעה מוצגת בקונסול כאשר המחלקה מאותחלת.
דקורטור של שיטה
דקורטורים של שיטה מוחלים על שיטות במחלקה ויכולים לשנות קריאות והתנהגות של שיטות. דקורטור של מתודה מקבל שלושה ארגומנטים.
- הפרוטוטייפ של המחלקה
- שם השיטה
- מתאר התכונה של השיטה
1function LogExecutionTime(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
2 const originalMethod = descriptor.value;
3
4 descriptor.value = function (...args: any[]) {
5 console.time(propertyKey);
6 const result = originalMethod.apply(this, args);
7 console.timeEnd(propertyKey);
8 return result;
9 };
10}
11
12class MathOperations {
13 @LogExecutionTime
14 add(a: number, b: number): number {
15 return a + b;
16 }
17}
18
19const math = new MathOperations();
20math.add(2, 3);
21// Output: add: 0.000ms (execution time is displayed)
בדוגמה זו, דקורטור LogExecutionTime
מיושם על השיטה, וזמן הביצוע של השיטה נרשם.
דקורטור גישה
דקורטורי גישה מיושמים על getter
או setter
של תכונות מחלקה. הם שימושיים להוספת התנהגות בעת שינוי ערכי תכונה.
1function LogAccess(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
2 const originalGet = descriptor.get;
3 const originalSet = descriptor.set;
4
5 if (originalGet) {
6 descriptor.get = function () {
7 console.log(`Getter called for ${propertyKey}`);
8 return originalGet.call(this);
9 };
10 }
11
12 if (originalSet) {
13 descriptor.set = function (value: any) {
14 console.log(`Setter called for ${propertyKey} with value: ${value}`);
15 originalSet.call(this, value);
16 };
17 }
18}
19
20class Car {
21 private _speed: number = 0;
22
23 @LogAccess
24 get speed() {
25 return this._speed;
26 }
27
28 set speed(value: number) {
29 this._speed = value;
30 }
31}
32
33const car = new Car();
34car.speed = 120; // Setter called for speed with value: 120
35console.log(car.speed); // Getter called for speed → 120
בדוגמה זו, נעשה שימוש במקשט גישה כדי לתעד פלט כאשר ה־getter וה־setter נקראים.
דקורטור תכונה
דקורטורי תכונה מיושמים על תכונות מחלקה, אך לא יכולים לשנות ישירות את ערך התכונה או את התנהגותה. הם משמשים לקבלת מטא-נתונים של תכונות.
1function Readonly(target: any, propertyKey: string) {
2 Object.defineProperty(target, propertyKey, {
3 writable: false
4 });
5}
6
7class Book {
8 @Readonly
9 title: string = "TypeScript Guide";
10}
11
12const book = new Book();
13book.title = "New Title"; // Error: Cannot assign to read only property 'title'
בדוגמה זו, דקורטור Readonly
מיושם על התכונה title
, והתכונה הופכת לקריאה בלבד.
דקורטור פרמטר
דקורטורי פרמטר מיושמים על הפרמטרים של שיטה. הם משמשים בדרך כלל לאחסון מטא-נתונים או לאימות פרמטרים. דקורטורים מקבלים שלושה ארגומנטים.
- הפרוטוטייפ של המחלקה
- שם השיטה
- אינדקס פרמטר
1function LogParameter(target: any, propertyKey: string, parameterIndex: number) {
2 console.log(`Parameter at index ${parameterIndex} in method ${propertyKey} was decorated.`);
3}
4
5class User {
6 greet(@LogParameter message: string) {
7 console.log(message);
8 }
9}
10
11const user = new User();
12user.greet('Hello!');
13// Output: Parameter at index 0 in method greet was decorated.
בדוגמה זו, דקורטור LogParameter
מיושם על הפרמטר הראשון של שיטת greet
, וכאשר השיטה מופעלת, הוא רושם שהפרמטר מעוטר.
דוגמאות מעשיות לדקורטורים
דקורטורים נפוצים בשימוש בפריימוורקים כמו Angular, במיוחד להזרקת תלות ולהגדרת מטא-נתונים. לדוגמה, השתמש בדקורטור @Component
להגדרת רכיבי Angular כפי שמוצג להלן.
1@Component({
2 selector: 'app-root',
3 template: '<h1>Hello World</h1>',
4})
5export class AppComponent {}
לפיכך, דקורטורים משמשים לעיתים קרובות כחלק מרכזי בפריימוורקים וספריות, ועוזרים לשמור על קוד תמציתי וברור.
סיכום דקורטורים
דקורטורים ב-TypeScript הם כלים חזקים המוסיפים באופן גמיש פונקציונליות למחלקות, שיטות ותכונות. שימוש בדקורטורים מותאמים אישית משפר תחזוקתיות ושימוש חוזר בקוד, ומאפשר הפשטה נוספת. לדקורטורים יש תפקיד חשוב בפריימוורקים כמו Angular ו-NestJS, והבנתם מסייעת להבין לעומק כיצד פריימוורקים אלו פועלים.
תוכלו לעקוב אחר המאמר שלמעלה באמצעות Visual Studio Code בערוץ היוטיוב שלנו. נא לבדוק גם את ערוץ היוטיוב.