В JavaScript нету привычной системы классов как в Java, или C#. В языке заместо этого есть система объектов, где каждый объект наследуется от другого, сохраняя его цепь прототипов. Однако мы имеем возможность писать более привычный код начиная с версии Es6.

1. Объявления класса

Для того чтобы объявить класс, нужно воспользоваться ключевым слово class.

class Animal {
  
}

После ключевого слова идёт название класса. Название можно не записывать - если мы объявляем класс через переменную. Чтобы создать экземпляр класса, обратимся к ключевому слову new.

class Animal {
  
}

var bird = new Animal();
bird.Msg = "Кар - Кар!";
console.log(bird.Msg)

2. Конструктор класса и поля, методы

Чтобы не записывать каждый раз свойства нашего экземпляра, напишем конструктор класса, чтобы писать его свойства при обьявлении. Для этого внутри класса нужно записать метод с названием constructor. Внутри методы мы пишем все свойства которые мы должны будем передать в скобки при объявлении экземпляра класса.

class Animal {
  constructor(Msg) {
    this.Msg = Msg;
  }
}

var bird = new Animal("Кар Кар");
console.log(bird); // Кар Кар

var cat = new Animal("Мяу Мяу");
console.log(cat); // Мяу мяу

Через ключевое слово this, мы обращаемся как бы к нашему новому экземпляру, и задаём ему поля через конструктор. Поля можно обозначить без ключевых слов внутри класса, просто написав его название. Они могут быть как со значениями, как и без.

class Animal {
  Msg = "я не знаю что мне говорить...";

  constructor (Msg) {
    if (Msg === "") return;
    this.Msg = Msg;
  }
}

var stranger = new Animal("");
console.log(stranger);  // я не знаю что говорить...

Таким образом мы можем создать поля внутри класса. Они не обязательно будут взаимодействовать с конструктором класса. Ещё можно создать приватные поля класса, не доступные из вне. Для этого используется префикс #.

class Animal {
  #Msg = "я не знаю что говорить...";

  constructor (Msg) {
    if (!Msg) return;
    this.#Msg = Msg;
  }
}

var bird = new Animal("Кря!");
bird.Msg = "Кур!"; // Получим ошибку

Таким же образом создаём публичные, и приватные методы класса. Методы это функции внутри класса.

class Animal {
  #Msg = "я не знаю что мне говорить...";

  constructor(Msg) {
    if (!Msg) return;
    this.Msg = Msg;
  }

  Message() {
    console.log(this.Msg);
  }
}

var bird = new Animal("Кур!");
bird.Message(); // Кур!

Наследование

Мы можем наследовать какой то класс от другого, тоесть передать все методы и свойства в этот класс, копируя их. Перепишем наш код

class Properties {
  Msg = "я не знаю...";

  constructor(Msg) {
    if (!Msg) return;
    this.Msg = Msg;
  }

  Message () {
    console.log(Msg);
  }
}

class Animal extends Properties
{ }

var bird = new Animal("Кря!");
bird.Message();