Menu

מתודות ומאפיינים סטטיים ב-JavaScript: מילת המפתח static

איך מתודות ומאפיינים סטטיים עובדים במחלקות של JavaScript: מתי להשתמש בהם, איך this מתנהג, ודפוס ה-factory שהם מאפשרים.

בדף הזה יש עורכים שאפשר להריץ - לערוך, להריץ ולראות את הפלט מיד.

איברים סטטיים שייכים למחלקה, לא למופע

רוב המתודות שכותבים במחלקה פועלות על מופע מסוים: user מסוים, circle מסוים. איברים סטטיים שונים. הם שייכים למחלקה עצמה. קוראים להם דרך שם המחלקה, לא דרך מופע.

double נמצאת על MathUtils, לא על המופעים שלה. יצירת מופע לא עוזרת: m.double הוא undefined. זה ההפך ממתודות רגילות, שנמצאות על המופעים (טכנית, על ה-prototype) ואינן נראות מהמחלקה.

המודל המחשבתי: מילת המפתח class יוצרת שני דברים: קבוצה של מתודות מופע (שמשמשות את new MathUtils()) וקבוצה של מתודות סטטיות (שמשמשות את MathUtils ישירות). מילת המפתח static בוחרת לאיזו קבוצה איבר נכנס.

השימוש הקלאסי: מתודות Factory

הסיבה הנפוצה ביותר לכתוב מתודה סטטית היא בנאי חלופי. ה-constructor האמיתי מקבל את הארגומנטים שהוא מקבל, אבל לעיתים קרובות רוצים דרכים אחרות לבנות אובייקט: מ-JSON, משורה במסד נתונים, מכתובת URL.

fromJSON לא משתמשת במשתמש, היא מייצרת אחד. זה בדיוק המצב שבו מתודה סטטית מתאימה. החלופה הייתה פונקציה חופשית בשם parseUser, אבל כשהיא נמצאת על המחלקה, התנהגות קשורה מקובצת יחד והכוונה ברורה במקום הקריאה.

מאפיינים סטטיים

אפשר גם להצמיד נתונים למחלקה עצמה:

Circle.PI משותף לכל העיגולים: זה קבוע על המחלקה, לא עותק בכל מופע. בתוך מתודות מופע, ניגשים אליו דרך שם המחלקה (Circle.PI), לא דרך this.

מאפיינים סטטיים שימושיים להגדרות, למטמונים משותפים לכל המופעים, למונים ולקבועים ברמת המחלקה.

this בתוך מתודה סטטית הוא המחלקה

בתוך מתודה רגילה, this הוא המופע. בתוך מתודה סטטית, this הוא המחלקה:

this.count בתוך increment פירושו Counter.count. זה אולי מרגיש מוזר בהתחלה, אבל זה מה שגורם לירושה של מתודות סטטיות לעבוד: this מפנה למחלקה שדרכה קראתם למתודה, לא למחלקה שהגדירה אותה.

מתודות סטטיות וירושה

מתודות סטטיות עוברות בירושה למחלקות יורשות. ומכיוון ש-this מצביע על המחלקה שדרכה נקראה המתודה, מתודות factory מייצרות אוטומטית את המחלקה היורשת הנכונה:

Animal.create משתמשת ב-new this(name). כשקוראים ל-Dog.create("Rex"), this הוא Dog, ולכן new this(name) בונה Dog. אם הייתם כותבים שם new Animal(name), תמיד היה נוצר Animal, והדפוס היה נשבר. זו הסיבה העיקרית ש-this במתודות סטטיות מצביע על המחלקה.

סטטי מול מופע: השוואה מעשית

הנה אותה לוגיקה, מחולקת בין שני הסגנונות:

שתיהן עושות את אותו חישוב. גרסת המופע קוראת נתונים מ-this.celsius. הגרסה הסטטית מקבלת את הקלט שלה כארגומנט. בחרו במתודת מופע כשהפעולה היא "משהו שהאובייקט הזה עושה"; בחרו במתודה סטטית כשהיא "משהו שהמחלקה הזו יודעת לחשב בהינתן קלט".

בלוקים סטטיים לאתחול

לפעמים אתחול של מאפיין סטטי דורש יותר מביטוי אחד: לולאה, תנאי, כמה ערכים שתלויים זה בזה. בשביל זה יש בלוקים סטטיים:

בלוק static { ... } רץ פעם אחת, כשהמחלקה מוגדרת. בתוכו, this הוא המחלקה. השתמשו בו לאתחול של כמה שלבים; להשמה אחת, שדה סטטי רגיל ברור יותר.

איברים סטטיים פרטיים

גם שדות סטטיים יכולים להיות פרטיים, עם הקידומת #. אפשר לגשת אליהם רק מתוך המחלקה:

#nextId חתום בתוך המחלקה. קוד חיצוני יכול לקרוא ל-IdGenerator.next() אבל לא יכול לגעת במונה או לאפס אותו. לשדות פרטיים יש דף משלהם בקרוב, אבל כדאי לדעת שהשילוב של static ו-# עובד.

מתי לא להשתמש ב-static

מתודות סטטיות הן דרך נחמדה לקבץ פונקציות עזר, אבל הן לא סיבה להפוך כל כלי עזר למחלקה. אם יש לכם קובץ מלא בפונקציות עצמאיות, ייצאו את הפונקציות: אל תעטפו אותן במחלקה שכל המתודות שלה סטטיות רק כדי ליצור מרחב שמות. מודול כבר עושה את העבודה הזו, ועושה אותה בצורה נקייה יותר.

השתמשו ב-static כש:

  • הפונקציה באמת שייכת למחלקה (factory, ממיר או מאמת לטיפוס הזה).
  • צריך מצב שמשותף לכל המופעים של המחלקה.
  • מחלקה יורשת עשויה לרצות לדרוס את ההתנהגות או לרשת אותה.

אחרת, פונקציה רגילה היא הכלי הפשוט יותר.

הבא בתור: שדות פרטיים

ראיתם לרגע את #nextId: זה התחביר של שדות פרטיים ב-JavaScript. הוא עובד גם לאיברי מופע וגם לאיברים סטטיים, והוא הדרך המודרנית להסתיר פרטי מימוש בתוך מחלקה. זה הדף הבא.

שאלות נפוצות

מה זו מתודה סטטית ב-JavaScript?

מתודה סטטית שייכת למחלקה עצמה, לא למופעים שלה. מצהירים עליה עם מילת המפתח static וקוראים לה דרך המחלקה: MyClass.doThing(). למופעים אין גישה אליה דרך this.doThing(), רק למחלקה.

מתי להשתמש במתודה סטטית במקום במתודת מופע?

השתמשו במתודה סטטית כשהפונקציה קשורה למחלקה אבל לא צריכה לקרוא או לשנות מופע מסוים. מקרים נפוצים: מתודות factory כמו User.fromJSON(...), פונקציות עזר כמו Math.max, וקבועים ששייכים למחלקה כמרחב שמות. אם המתודה צריכה ש-this יצביע על מופע, זו מתודת מופע.

האם מתודות סטטיות יכולות לגשת למאפיינים של מופע?

לא ישירות. בתוך מתודה סטטית, this מפנה למחלקה ולא למופע, כך ש-this.name קורא מאפיין סטטי ולא שדה של מופע. אם צריך נתונים של מופע, העבירו את המופע כארגומנט: static summarize(user) { return user.name; }.

האם מתודות סטטיות עוברות בירושה ב-JavaScript?

כן. כשמחלקה יורשת מרחיבה מחלקת אב, המתודות הסטטיות של האב זמינות גם במחלקה היורשת. בתוך מתודה סטטית, this מפנה למחלקה שדרכה קראתם לה, וזה מה שגורם למתודות factory סטטיות לעבוד נכון גם במחלקות יורשות.

איור של שפות התכנות ב-Coddy

ללמוד תכנות עם Coddy

להתחיל