Декораторы — это действительно полезная функция, которая позволяет нам расширять классы JavaScript. Самый популярный случай использования декораторов — это когда мы хотим сохранить единственную ответственность (SOLID). В этой статье я собираюсь шаг за шагом показать вам, как настроить среду и использовать функцию JavaScript уже сегодня!
Конфигурация
Первое, что нам нужно, это установить несколько пакетов, которые помогут нам настроить babel и webpack, мы должны сделать это, потому что мы используем современный JavaScript, который еще не вошел в стандарт еще.
Список пакетов:
Я также приложил пару скриптов, которые запускают сборщик веб-пакетов.
Как вы заметили, помимо пакетов по умолчанию я установил несколько дополнительных в качестве пакетов зависимостей для разработчиков, а именно:
@babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties
Первый плагин включает функцию декоратора, а второй позволяет нам использовать свойства внутри класса, не беспокоясь о совместимости со старыми браузерами. Пришло время настроить bable:
И настроим веббэк, определим правила преобразования нашего кода в совместимый код для всех браузеров, нам нужно описать порядок загрузчиков, входной и выходной файл. Я также добавляю следующие плагины:
HtmlWebpackPlugin() CleanWebpackPlugin()
Плагин HtmlWebpackPlugin() создает HTML-страницу, на которой будет выполняться наш код JavaScript, а CleanWebpackPlugin() — это просто служебный плагин, очищающий нашу папку dist после каждого сборка сборки. Полная конфигурация webpack:
Декоратор метода
Время кодировать, я подготовил простой пример, который иллюстрирует все преимущества использования декоратора:
У нас есть очень простая функция sum(a, b), в ее обязанности входит только суммирование двух значений, но мы хотим регистрировать каждую часть вычисления, а не модифицировать текущую реализацию.
Как видите, декоратор имеет особый синтаксис, начинающийся с символа @. Функция logging(target) — это просто прокси, мы могли бы поймать обернутую функцию декоратора, например:
const originalFn = target.descriptor.value
Итак, следующим шагом является переписывание текущего значения дескриптора, которое будет принимать некоторые аргументы, необходимые для получения возможности передавать числа для суммирования, которые будут применяться к исходной функции.
В промежутках вычислений мы добавляем дополнительные функции регистрации, не изменяя исходную логику sum(a, b).
Свойство дескриптора в деталях
Между прочим, свойство дескриптора обладает большей силой, чем вы думаете. Мы можем управлять доступностью объекта, используя следующие свойства:
target.descriptor.value target.descriptor.writable target.descriptor.enumerable target.descriptor.configurable
- target.descriptor.value — значение свойства (вы видели это, когда мы получили оригинальную функцию);
- target.descriptor.writable — свойство может быть изменено;
- target.descriptor.enumerable — свойство проявляется во время перечисления, например, в циклах;
- target.descriptor.configurable — дескриптор свойства может быть изменен, а свойство может быть удалено из текущего объекта.
Краткое содержание
Мы рассмотрели главное преимущество использования декоратора, он действительно помогает нам, когда мы хотим расширить объект с помощью дополнительной логики, а не изменять его исходное поведение, и дает нашим классам одну причину для изменения.
Полный код вы можете увидеть здесь.