Статические поля и методы
Кроме обычных полей и методов класс может определять статические поля и методы. В отличие от обычных полей/свойств и методов они относятся ко всему классу, а не к отдельному объекту.
Статические поля
Статические поля хранят состояния класса в целом, а не отдельного объекта. Перед названием статического поля ставится ключевое слово static
:
class Person{
static retirementAge = 65;
constructor(name, age){
this.name = name;
this.age = age;
}
print(){
console.log(`Имя: ${this.name} Возраст: ${this.age}`);
}
}
// 65
console.log(Person.retirementAge);
Person.retirementAge = 62;
// 62
console.log(Person.retirementAge);
Здесь в классе Person
определено статическое поле retirementAge
, которое хранит условный возраст выхода на пенсию:
static retirementAge = 65;
Это поле относится ко всему классу Person
в целом и описывает состояние всего класса в целом. Ведь, как правило, есть некий общий возраст выхода на пенсию, принтый для всех (не берем в расчет отдельные случаи для отдельных профессий). И поэтому для обращения к статическому полю применяется имя класса, а не имя какого-либо объекта. Используя имя класса, мы можем получить или установить его значение:
Person.retirementAge = 62;
// 62
console.log(Person.retirementAge);
При этом мы не можем в нестатических методах и конструкторе класса обращаться к этим полям через this
, наподобие следующего:
print(){
console.log(`Имя: ${this.name} Возраст: ${this.age}`);
// к статическому полю нельзя обратиться через this
console.log(`Пенсионный возраст: ${this.retirementAge}`);
}
Если мы все таки хотим обратиться к статическим полям и методам внутри нестатических методов и конструкторе класса, то опять же, как и в общем случае, необходимо использовать имя класса:
print(){
console.log(`Имя: ${this.name} Возраст: ${this.age}`);
console.log(`Пенсионный возраст: ${Person.retirementAge}`);
}
Статические методы
Статические методы, как и статические поля, определяются для всего класса в целом, а не для отдельного объекта. Для их определения перед названием метода ставится оператор static
:
class Person{
constructor(name, age){
this.name = name;
this.age = age;
}
print(){
console.log(`Имя: ${this.name} Возраст: ${this.age}`);
}
static printClassInfo(){
console.log("Класс Person представляет человека");
}
}
// Класс Person представляет человека
Person.printClassInfo();
Здесь определен статический метод printClassInfo()
, который для простоты просто выводит некоторое сообщение. В отличие от обычных нестатических методов, которые определяют поведение класса, статические методы определяют поведение для всего класса. Поэтому для их вызова применяется имя класса, а не имя объекта:
Person.printClassInfo();
Поскольку статический метод относится классу в целом, а не к объекту, то мы не можем обращаться в нем к нестатическим полям/свойствам и методам объекта, наподобие следующего:
class Person{
constructor(name, age){
this.name = name;
this.age = age;
}
print(){
console.log(`Имя: ${this.name} Возраст: ${this.age}`);
}
// для статического метода this.age не существует
static printAge(){ console.log(this.age); }
}
// undefined
Person.printAge();
Если необходимо в статическом методе обратиться к свойствам объекта, то мы можем опеределить в методе параметр, через который в метод будет передаваться объект:
class Person{
constructor(name, age){
this.name = name;
this.age = age;
}
static print(person){
console.log(`Имя: ${person.name} Возраст: ${person.age}`);
}
}
const tom = new Person("Tom", 37);
const bob = new Person("Bob", 41);
// Tom 37
Person.print(tom);
// Bob 41
Person.print(bob);
Однако мы можем использовать в статических методах слово this
для обращения к статическим полям и другим статическим методам:
class Person{
static retirementAge = 65;
constructor(name, age){
this.name = name;
this.age = age;
}
print(){
console.log(`Имя: ${this.name} Возраст: ${this.age}`);
}
static calculateRestAges(person){
if(this.retirementAge > person.age){
const restAges = this.retirementAge - person.age;
console.log(`До пенсии осталось ${restAges} лет`);
}
else console.log("Вы уже на пенсии");
}
}
const tom = new Person("Tom", 37);
// До пенсии осталось 28 лет
Person.calculateRestAges(tom);
const bob = new Person("Bob", 71);
// Вы уже на пенсии
Person.calculateRestAges(bob);
Здесь определен статический метод calculateRestAges()
, который расчитывает, сколько определенному человеку осталось до пенсии. И для вычисления он обращается к статическому полю retirementAge
:
const restAges = this.retirementAge - person.age;
Приватные статические поля и методы
Как и обычные поля и методы статические поля и методы могут быть приватными. Такие поля и методы доступны только из других статических методов класса:
class Person{
static #retirementAge = 65;
constructor(name, age){
this.name = name;
this.age = age;
}
print(){
console.log(`Имя: ${this.name} Возраст: ${this.age}`);
}
static calculateRestAges(person){
if(this.#retirementAge > person.age){
const restAges = this.#retirementAge - person.age;
console.log(`До пенсии осталось ${restAges} лет`);
}
else console.log("Вы уже на пенсии");
}
}
// Ошибка: поле retirementAge -приватное
console.log(Person.#retirementAge);
const tom = new Person("Tom", 37);
В отличие от предыдущего примера теперь статическое поле retirementAge
- приватное. И теперь к нему можно обратиться только внутри статических методов класса.