שדות ושיטות של כיתות

שדות

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

class MyClass {
    myField;
}

const myClassInstance = new MyClass();

myClassInstance;
> MyClass { myField: undefined }

אפשר לאתחל שדה עם ערך. לרוב זהו ערך ברירת המחדל הלוגיקה בתוך הכיתה יכולה להחליף:

class MyClass {
    myResult = false;
    set setValue( myValue ) {
        this.myResult = myValue;
    }
}
const myClassInstance = new MyClass();

myClassInstance;
> Object { myResult: false }

myClassInstance.setValue = true;

myClassInstance;\
> Object { myResult: true }

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

class MyClass {
    myField = true;
}

const myClassInstance = new MyClass();

myClassInstance.myField;
> true

myClassInstance.myField = false;

myClassInstance.myField;
> false;

השדות הם הבסיס לכמה מהתכונות המתקדמות יותר של הכיתות.

שדות פרטיים ו-methods

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

כדי להפוך נכס לפרטי, צריך להוסיף # בתחילת המזהה כאשר עליך:

class MyClass {
    #myPrivateField = true;
    #myPrivateMethod() {}
}
const myClassInstance = new MyClass();

myClassInstance;
> MyClass { #myPrivateField: true }
    #myPrivateField: true
    <prototype>: Object {  }
        constructor: class MyClass {}
        <prototype>: Object {  }

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

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

class MyClass {
    #myResult = false;
    set setValue( myValue ) {
        this.#myResult = myValue;
    }
}
const myClassInstance = new MyClass();

myClassInstance;
> MyClass { #myResult: false }

myClassInstance.#myResult = true;
> Uncaught SyntaxError: reference to undeclared private field or method #myResult

myClassInstance.setValue = true;

myClassInstance;\
> MyClass { #myResult: true }

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

class MyClass {
    #myPrivateField = true;
    #myPrivateMethod() {
        console.log( "This is inside a private method." );
    }
}
const myClassInstance = new MyClass();

myClassInstance;
> MyClass {#myPrivateField: true}

myClassInstance.#myPrivateField;
> true

myClassInstance.#myPrivateMethod();
> "This is inside a private method."
class MyClass {
    #myPrivateField = true;
    #myPrivateMethod() {
        console.log( "This is inside a private method." );
    }
}
const myClassInstance = new MyClass();

myClassInstance;
> MyClass {#myPrivateField: true}

myClassInstance.#myPrivateField;
> Uncaught SyntaxError: reference to undeclared private field or method #myPrivateField

myClassInstance.#myPrivateMethod();
> Uncaught SyntaxError: reference to undeclared private field or method #myPrivateMethod

שדות פרטיים מוגבלים לגוף הכיתה שמכיל אותם, כלומר שאפילו כיתות צאצא לא יכולות לגשת לשדות פרטיים שמשויכים כיתת הורה:

class MyClass {
    #myPrivateField = true;
}
class ChildClass extends MyClass {
    childMethod() {
        console.log( this.#myPrivateField );
    }
}
> Uncaught SyntaxError: reference to undeclared private field or method #myPrivateField

שדות סטטיים ושיטות

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

כדי להגדיר methods ושדות סטטיים בגוף הכיתה, צריך להשתמש בפונקציה static מילת מפתח:

class MyClass {
    static myStaticField;
    static myStaticMethod() {}
}
const myClassInstance = new MyClass();

אפשר להשתמש בסימון הנקודות גם כדי ליצור שיטה סטטית:

class MyClass {
    constructor() {}
}
MyClass.myStaticMethod = function() {}

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

class MyClass {
    static myStaticField = true;
    static myStaticMethod() {
        console.log( "A static method." );
    }
}
const myClassInstance = new MyClass();

myClassInstance.myStaticField;
> undefined

myClassInstance.myStaticMethod();
> Uncaught TypeError: myClassInstance.myStaticMethod is not a function

MyClass.myStaticField;
> true

MyClass.myStaticMethod();
> "A static method."

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

class User {
    constructor( name, email ) {
        this.name = name;
        this.email = email;
    }
    static fromObject( myObject ) {
        return new User( myObject.name, myObject.email ?? "Omitted" );
    }
}
const userObject = {
    "name" : "My Name",
    "email" : "my@email.address"
};
const secondUserObject = {
    "name" : "My Name"
};

const firstUser = User.fromObject( userObject );
const secondUser = User.fromObject( secondUserObject );

firstUser;
> Object { name: "My Name", email: "my@email.address" }

secondUser;
> Object { name: "My Name", email: "Omitted" }

בדיקת ההבנה

לאילו מסוגי השדות הבאים אפשר לגשת רק? בתוך הכיתה?

שדות פרטיים
שדות כיתה
Static fields