Мы с моей командой обсудили использование классов в наших приложениях. Были некоторые опасения по поводу их использования, как если бы они были классами 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 (более конкретные примеры). Если вам интересно просмотреть более подробное объяснение функций и синтаксиса класса, посмотрите видео ниже.