Поля и методы класса

Поля класса объявляются непосредственно в теле класса, а не добавляются явно как свойство значения 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 MyClass {
    myField = true;
}

const myClassInstance = new MyClass();

myClassInstance.myField;
> true

myClassInstance.myField = false;

myClassInstance.myField;
> false;

Поля обеспечивают основу для некоторых более продвинутых функций классов.

Частные поля и методы

Приватные поля и методы недоступны вне класса. Частное свойство связано с экземпляром класса, а это означает, что каждый экземпляр содержит свой собственный набор частных полей и методов, определенных в классе.

Чтобы сделать свойство частным, добавьте # в начало идентификатора при его объявлении:

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

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

Приватное поле должно быть объявлено в теле содержащего его класса. Вы можете изменить его значение позже как свойство this , но вы не сможете создать поле с помощью this .

К закрытым полям нельзя получить доступ из другого места скрипта. Это предотвращает изменение свойств данных за пределами методов получения и установки, предоставленных для взаимодействия со значениями, которые они содержат, а также предотвращает прямой доступ к методам, предназначенным только для использования внутри самого класса.

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

Статические поля и методы

Статические поля и методы являются членами самого класса, а не членами экземпляров этого класса. По этой причине статические поля предоставляют центральную точку для данных, которые не будут уникальными для каждого экземпляра класса, но на которые могут потребоваться ссылки этим экземплярам — например, общая информация о конфигурации. Статические методы часто представляют собой служебные функции для работы с экземплярами класса, например для сравнения или сортировки экземпляров по содержащемуся в них полю.

Чтобы определить статические поля и методы в теле класса, используйте ключевое слово static :

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

Вы также можете использовать точечную нотацию для создания статического метода:

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

Вы не можете получить доступ к статическим свойствам из экземпляра их класса, но они доступны в конструкторе класса:

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
Частные поля
Поля класса