Мы с моей командой обсудили использование классов в наших приложениях. Были некоторые опасения по поводу их использования, как если бы они были классами Java (вспомните StrategyIteratorDescriptorAdapterOrderBroadcaster). Однако мы пришли к выводу, что существует четкое различие между тем, когда их использовать, а когда нет.

Когда их использовать

Наша команда пришла к интересному выводу: в чем разница между классом и функцией? В javascript не так много. Однако, если подумать об этом в более широком смысле, мой товарищ по команде заявил:

Мы должны использовать классы для функций, которые имеют состояние.

Это предложение прояснило это так точно для меня. Как разработчик Angular, я без проблем использовал классы для сервисов и контроллеров. Мне понравился синтаксис и ясность, которые они привносят в мои приложения. Однако я всегда изо всех сил пытался использовать их в Директивах и Фабриках.

В конечном итоге все сводится к следующему: Angular создает экземпляры (вызывая new для аргумента, переданного при представлении функции или класса) Сервисы и Контроллеры, но не директивы, фабрики, фильтры и т. д.

Причина, по которой они создаются, а не вызываются и используются возвращаемый объект, заключается в том, что они содержат состояние во всем приложении. В случае служб они используются как синглтоны и могут содержать внутри себя набор данных для всего приложения. Кроме того, контроллеры поддерживают состояние своего компонента или представления.

Однако директивы, фабрики и фильтры — это просто функции, используемые для генерации объектов или результатов, которые не заботятся о состоянии приложения.

tl;dr Если у него есть состояние и функции, использующие это состояние, класс является хорошим вариантом.

Как работают классы в Babel

Классы — это просто синтаксический сахар. В конечном счете, при транспиляции Babel классы становятся просто функциями.

Функциональность конструктора выполняется непосредственно в объявлении функции, после чего следует настройка прототипов функций в классе.

Babel добавляет дополнительную защиту от сбоев, чтобы разработчики не могли выполнять класс как функцию, но это все. Функциональность транспиляции довольно проста!

class Test {  
  constructor(name) {
    this.name = name;
  }
  sayHi() {
    console.log(`Hi, ${this.name}.`);
  }
}
new Test('Evan').sayHi();

становится:

function _classCallCheck(instance, Constructor) {  
    if (!(instance instanceof Constructor)) {
        throw new TypeError('Cannot call a class as a function');
    }
}
var Test = function () {  
    function Test(name) {
        _classCallCheck(this, Test);
        this.name = name;
    }
    Test.prototype.sayHi = function sayHi() {
        console.log('Hi, ' + this.name + '.');
    };
    return Test;
}();
new Test('Evan').sayHi();

Вывод

Babel позволяет нам использовать (что я считаю) очень чистый синтаксис. Я расскажу об этом синтаксисе в следующем посте о реализации классов в Angular (более конкретные примеры). Если вам интересно просмотреть более подробное объяснение функций и синтаксиса класса, посмотрите видео ниже.