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