-
יש לי אובייקט שנראה כך
export class myClass{ x:number; y:number; z:number; constructor( x:number,y:number ) { this.x = x; this.y = y; this.z =this.x*this.y; } }
אני מנסה ליצור ממנו מופע כך
MC:myClass {x:10,y:5}
אני מצפה ש-Z יחושב אוטומטית. בפועל אני מקבל שגיאה ש-
Property 'z' is missing
השאלה היא כיצד ניתן לגרום למחשב להבין שיש התייחסות ל-z.
תודה רבה -
@upsilon01 אמר באתחול אובייקט ב-TS.:
ואז פעולת החישוב תתבצע כשקוראים את הערך שלו
אבל מצד שני החישוב יתבצע בכל קריאה.
אבל גם לזה יש פתרון, על ידי שמירת התוצאה של החישוב.
אבל כל זה לא רלוונטי בחישוב כל כך פשוט. -
@yyy המחלקה הבאה תתן לך אותה תוצאה בחצי קוד:
class shortClass{ z:number; constructor(private x:number, private y:number){ this.z = x * y; } }
איך זה קורה? כשאתה מעביר ארגומנטים לקונסטרקטור, אם אתה מצהיר עליהם פרייבט או פאבליק, TS מבין שהם אמורים להיות נכסים של המחלקה ולא משתנים מקומיים, ומבצע עבורך את העבודה.
-
כעת נתקלת בבעיה דומה:
האובייקט כעת נראה כך:export class myClass{ x:number; y:number=0; constructor( x:number ) { this.x = x; } }
נתון מערך ריק של האובייקטים
myClasses: myClass[] = [];
וכעת אני מנסה לדחוף עם push אובייקט חדש
this.myClasses.push({x:4});
גם כאן יש שגיאה שהוא רוצה את הערך של y למרות שהוא קבוע על 0. איך פותרים את זה?
-
@yyy כדאי להימנע מיצירת מופעים עבור מחלקות בצורה ליטרלית משום שהPrototype שלהם יהיה זהה לזה של Object.
ההשלכות המצערות:
- האובייקט לא יכיל את המתודות והProperties של המחלקה.
- ההצבות (בתוך הבנאי ומחוצה לו) לא יתבצעו (התגלית שהערך של השדה Y במופע שיצרת יהיה זהה ל
undefined
לא אמורה להיות מפתיעה במיוחד כעת). - השימוש בisPrototypeOf ו instanceof לא יניב את התוצאה הרצויה (וכן כל המתודות שבPrototype).
מסקנה:
- היכן שהשימוש בObject literal נחוץ (ומתאפשר) השתמש בInterface לציון הType (עקב הצורך בערך דיפולטיבי עבור Y האפשרות לא רלוונטית עבורך)
- צור מופעים עבור מחלקות באמצעות הבנאי:
class ZeroYCoordinate { public readonly y: number = 0; constructor(public x: number) { } } const points = [new ZeroYCoordinate(4)]
** שינוי
Prototype
אפשרי באמצעות השימוש בsetPrototypeOf, אם כי הדבר אינו מהווה פתרון מקיף לכל הבעיות שציינתי. -