Pola i metody klas

Pola

Pola klas są zadeklarowane bezpośrednio w treści klasy, a nie dodawane jako właściwości wartości this. Wynik jest jednak taki sam – właściwość zdefiniowana w instancjach tej klasy jest taka sama.

class MyClass {
    myField;
}

const myClassInstance = new MyClass();

myClassInstance;
> MyClass { myField: undefined }

Możesz zainicjować pole za pomocą wartości. Jest to często wartość domyślna, którą logika w klasie może zastąpić:

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 }

Pola klas działają tak samo z właściwościami dołączonymi do klasy za pomocą właściwości this. Oznacza to, że można je otwierać i modyfikować spoza klasy tak jak każdą inną usługę.

class MyClass {
    myField = true;
}

const myClassInstance = new MyClass();

myClassInstance.myField;
> true

myClassInstance.myField = false;

myClassInstance.myField;
> false;

Pola są podstawą niektórych bardziej zaawansowanych funkcji zajęć.

Prywatne pola i metody

Pola i metody prywatne są niedostępne poza klasą. Usługa prywatna jest powiązana z instancją klasy, co oznacza, że każda instancja zawiera własny zestaw prywatnych pól i metod zdefiniowanych w klasie.

Aby ustawić usługę jako prywatną, dodaj # na początku identyfikatora podczas jego zadeklarowania:

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

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

Prywatne pole musi być zadeklarowane w treści klasy zawierającej. Możesz później zmienić jego wartość jako właściwość this, ale nie możesz tego zrobić za pomocą this.

Pola prywatne nie są dostępne z innych miejsc w skrypcie. Zapobiega to zmianie właściwości danych poza metodami metod pobierania i ustawiania, które służą do interakcji z zawartymi w nich wartościami, oraz uniemożliwia bezpośredni dostęp do metod przeznaczonych wyłącznie do użytku w klasie.

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 }

Pamiętaj jednak, że konsole programisty w przeglądarkach są zwykle bardzo mało restrykcyjne, choć niespójne, jeśli chodzi o zezwalanie na dostęp do prywatnych pól na potrzeby debugowania:

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

Pola prywatne są ściśle ograniczone do treści klasy, która je zawiera, co oznacza, że nawet klasy podrzędne nie mają dostępu do pól prywatnych powiązanych z klasą nadrzędną:

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

Pola i metody statyczne

Pola i metody statyczne należą do samej klasy, a nie do jej instancji. Z tego względu pola statyczne stanowią centralny punkt danych, które nie będą unikalne dla każdej instancji klasy, ale mogą się odwoływać do tych instancji, na przykład do udostępnionych informacji o konfiguracji. Metody statyczne są często przydatne podczas pracy z instancjami klasy, np. porównywania lub sortowania instancji względem pola, które się w nich znajdują.

Aby zdefiniować pola i metody statyczne w treści klasy, użyj słowa kluczowego static:

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

Możesz też użyć notacji punktowej do utworzenia metody statycznej:

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

Nie możesz uzyskać dostępu do właściwości statycznych z poziomu instancji ich klasy, ale są one dostępne w konstruktorze klas:

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."

Z technicznego punktu widzenia nie są one wymagane, ale sprawdzoną metodą tworzenia narzędzi do pracy z instancjami klasy jest używanie metod statycznych. Może to być na przykład metoda statyczna służąca do sortowania instancji klasy lub statyczna metoda fabrycznego, która zawiera konfigurację niezbędną do utworzenia instancji klasy, a następnie zwraca instancję klasy:

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" }

Sprawdź swoją wiedzę

Do których z tych typów pól można uzyskać dostęp wyłącznie z poziomu klasy?

Pola prywatne
Pola zajęć
Static fields