July 6, 2023

Классы

Классы - это синтаксический сахар, в основе которого лежат прототипы

Для определения класса мы пишем:

class Person { ... }

Название класса всегда начинается с большой буквы

Вызывается же класс путем:

const person = new Person()

Когда класс вызывается, то создается объект со всеми методами и свойствами, которые мы указали и так же вызывается метод constructor - это метод, в котором инициализируется объект с передаными данными

class Person {
 constructor(name, age) {
  this.name = name;
  this.age = age;
 }
}

const person = new Person('Alex', 30);

console.log(person); // Результат: Person { name: 'Alex', age: 30 }

this используется так же как и в объектах, указывает на класс, в котором используется исходя из своего контекста

Классы имеют свойства и методы (они доступны вне класса) - это публичные данные, которые могут использоваться вне класса

class Person {
 name = 'Alex';

 sayOk() {
  console.log(1);
 }
}

const person = new Person();

console.log(person.name); // Результат: 'Alex'
person.sayOk(); // Результат: 1

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

Если мы заходим дополнить наш конструктор дополнительными данными, то для этого внутри него нужно вызвать метод super, который принимает в себя старые значения наследоваемого класса, если же это не сделать, то мы утрачиваем свойства наследоваеммого класса (получаем ошибку)

Так же это касается и методов, для доступа к внутренностям методов класса, которого мы наследоваем, нужно так же указывать метод super()

class Person {
 constructor(name) {
  this.name = name;
 }

 sayOk() {
  console.log(1);
 }
}

class Alex extends Person { 
 constructor(name, age) {
  super(name);
  this.age = age;
 } 
 
 sayOk() {
  super.sayOk();
  console.log(2);
 }
}

class Mike extends Person {
 constructor(age) {
  this.age = age; // Произойдет ошибка, так как нет методы super()
 }
}

У классов имеются статические методы и свойства - это то, что присваивается именно классу, а не созданному объекту на его основе (они наследуются)

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

class Person {
 static PERSON_HASH = 3123;
 
 sayHi() {
  console.log(this.PERSON_HASH); // Резульат: undefined
  console.log(Person.PERSON_HASH); // Результат: 3123
 }
}

const person = new Person();

console.log(person.PERSON_HASH); // Результат: undefined
console.log(Person.PERSON_HASH); // Результат: 3123

Приватные методы и свойства

У классов имеются приватные методы и свойства - они предотвращают их использование вне класса (они не наследуются)

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

class Person {
 #age = 30
 age = 30
}

const person = new Person()

console.log(person.age); // Результат: 30
console.log(person.#age); // Не будет доступен (виден)

Защищенные методы и свойства

У классов имеются защищенные методы и свойства - в отличии от приватных, защищенные всего лишь соглашение по написанию и обозначение того, что их нельзя использовать вне класса

Обычно для манипуляции с защищенными свойствами используются геттеры и сеттеры, они и выступают в роли тех, к чему мы будем обращаться вне класса

class Person {
 _water = 1000;

 get water() {
  return this._water;
 }
 
 set water(value) {
  this._water = value;
 }
}

сonst person = new Person()

console.log(person.water); // Результат: 1000

Мы можем не допустить сеттер для свойств и соответственно изменять будет нельзя эти свойства, так же внутри сеттеров мы можем делать проверки на удовлевторяющие нас значение

Для проверки, того принадлежит ли объект какому-то классу мы используем instanceof

const arr = [1, 2, 3];
const num = 1;
class Person {}
const person = new Person();

console.log(arr instanceof Array); // Результат: true
console.log(num instanceof Number); // Результат: true
console.log(person instanceof Person); // Результат: true

Мы так же можем создавать свои классы, которые наследуются от существующих классов, как бы расширяя их

class PowerArray extends Array {
 isLarge() {
  return this.length >= 2;
 }
}

const arr = new PowerArray(1, 2, 3);

console.log(arr.isLarge()); // Результат: true