#8 Javascript классы

poster
В es6 были добавлены классы. Мы разберем чем они отличаются от прототипов и как их описывать. Познакомимся с constructor, super, прототипными и статическими методами.
Понравилось? Поделитесь с друзьями!
Понравилось?
Поделитесь с друзьями!
Комментарии
Текст видео

В том уроке мы с вами разберем, как писать классы в ecmascript 6.

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

В javascript не существует классов и в ес5 мы использовали функции и прототипы, чтобы описывать классы. В ес6 не придумали ничего нового. Просто добавили синтаксический сахар для описания все тех же прототипов.

Как же выглядит класс описаный с помощью классов ес6?

class SimpleDate {
  constructor (year, month, day) {
    this.year = year;
    this.month = month;
    this.day = day;
  }
}

const today = new SimpleDate(2017, 1, 28)
console.log(today)

с помощью слова class мы описали новый класс. Также мы добавили метод constructor, который принимает year, month, day и записывает их в this. Мы создали переменную today, которая является екземпляром класса SimpleDate.

Давайте добавим метод toString, который будет возвращать дату в человеческом формате

class SimpleDate {
  constructor (year, month, day) {
    this.year = year;
    this.month = month;
    this.day = day;
  }

  toString () {
    return `${this.day}/${this.month}/${this.year}`;
  }
}

const today = new SimpleDate(2017, 1, 28)
console.log(today.toString())

Теперь у екземпляра класса появился метод toString, вызывая который мы получаем красивый вывод даты.

Также мы можем использовать наследование в классах с помощью слова extend. Давайте создадим класс OtherDate, который будет наследоваться от SimpleDate.

class OtherDate extends SimpleDate {
}

Для того, чтобы выполнить конструктор парент класса мы используем метод super и передаем в него аргументы. Super используется для того, чтобы обращатся к родительскому классу.

class OtherDate extends SimpleDate {
  constructor(year, month, day) {
    super(year, month, day)
  }
}
const tomorrow = new OtherDate(2017, 1, 29)
console.log(tomorrow.toString())

Как вы видите, мы вызвали конструктор парента и также у нас есть доступ к всем методам из парент класса. Именно поэтому метод toString у нас сработал

Давайте теперь пеопределим метод toString с другим выводом

class OtherDate extends SimpleDate {
  constructor(year, month, day) {
    super(year, month, day)
  }

  toString () {
    return `${this.day}.${this.month}.${this.year}`;
  }
}

Не нужно думать, что классы в ес6 это какая-то магия. Если мы посмотрим, что такое класс SimpleDate, то увидим, что это просто функция

typeof SimpleDate

То есть классы создают обычные функции с прототипным наследованием. Но вы не можете вызвать класс напрямую как функцию

SimpleDate()

У нас вывалится ошибка

TypeError: Classes can’t be function-called

потому-что классы нельзя вызывать напрямую.

Описав метод toString мы описывали метод прототипа

Также классам можно добавлять кроме прототипных методов, статические методы. Они будут является методами самого класса, а не методами prototype.

Если мы напишем в классе OtherDate метод hello

static hello() {
  console.log('hello OtherDate');
}

То мы можем вызвать его с помощью OtherDate.hello(). В прототипах он доступен не будет.

И на последок пища для размышлений о классах. В Javascript коммьюнити классы считаются весьма спорным функционалом javascript. И применять их нужно с оглядкой. Например многие люди предпочитают писать модуль с набором функций, чем класс. Их легче поддерживать, експортировать и переиспользовать, не приходится использовать this и не нужно постоянно помнить а какой у меня контекст. Также нет проблем с кучей классов, которые наследуются друг от друга и сложно отдебажить какой метод откуда доступен. Поэтому лучше два раза подумайте прежде чем их использовать.

Если у вас возникли какие-то вопросы или комментарии, пишите их прямо под этим видео.

Только зарегистрированные пользователи могут оставлять комментарии.  Войдите, пожалуйста.
Guru-Js
6 дней назад
Зачем в OtherDate продублировал метод toString()? Ведь если в constructor класcа OtherDate есть super можем взять toString() с родителя SimpleData
monsterlessons
1 день назад назад
Конечно можно, но мы его хотим переопределить(т.е. сделать отдельную реализацию для OtherDate), поэтому мы его и описываем в OtherDate.
Moe Green
11 месяцев назад
Можно ли сказать так - JavaScript изначально был создан как функциональный язык и у него не было и нет поддержки полноценных классов? А все попытки "создать" таковые - это притянуть ситуацию за уши? И точно также с асинхронностью? У меня пока что мозги склеиваются от все этих Promise и async-await ))
monsterlessons
11 месяцев назад
Он не функциональный вообще, но у него не было и нет поддержки полноценных классов. Да это попытки создать таковые Async await - это такое же сахар вокруг промисов как и class вокруг prototype.
Valerii Kuzivanov
2 лет назад
Пока не понятно в чем сложность работы с классами нежели с функциями и прототипами. Я из php вернулся, так там вполне себе удобно классы реализованы.
monsterlessons
2 лет назад
Сложность в том, что в php есть нормальный классы как сущность, а в javascript нет. И для реализации классов используется костыль в виде прототипов.
Evgeny Listopad
1год назад назад
Будешь делать видео уроки по typescript?
monsterlessons
1год назад назад
В планах есть, но пока не хватает времени.
Valerii Kuzivanov
10 месяцев назад
Спустя 11 месяцев активного использования JS, скажу: Я так и не нашел толковое применение классов =) Единственно где используем так это в react/angular в качестве обертки для компонента. В том же node.js как по мне проще сделать module.exports = {//... тут методы} Всё равно приватных методов нету, наследовать особо нечего, я хз. Надеюсь через 11 мес появится другое мнение)))
monsterlessons
10 месяцев назад
Ну на вкус и цвет. Я считаю, что если вам что-то кажется ненужным, то просто не используйте его (как вы, собственно, и делаете). P.S. можете попробовать Typescript там классы повеселее будут.
Valerii Kuzivanov
6 месяцев назад
Спустя 4 месяца вернулся сообщить, что нашел применение Классу!!! На днях пилил плагин-обертку на Vue.js для работы с websockets, так вот там класс зашел как никогда кстати! При создании экземпляра принимает url и опции и реализовывает приватные и открытые методы, также засунул туда паттерн Observer. Получилось красиво в компонентах выглядит так: this.$ws.connect(), this.$ws.reconnect(), this.$ws.on('eventName', callback) и тд.
monsterlessons
6 месяцев назад
Поздравляю) Рад, что получилось.