Декораторы JavaScript были языковой функцией с момента выхода ES2015, но они все еще в значительной степени экспериментальные в движках JavaScript, которые ее поддерживают. Кто они такие? Если вы знакомы с Java, вы знаете, как можно обернуть методы через аннотации. Суть этого: декоратор оборачивает метод класса JavaScript в другую функцию, и он вызывается с помощью аннотации.

Я буду использовать NodeJS в качестве примера кода, поэтому потребуется несколько модулей, плагинов и конфигураций.

Установка

  1. инициализировать проект npm
  2. установить инструменты командной строки babel; нам это понадобится, чтобы перенести декорированные методы
  3. установить плагины, необходимые для транспиляции
npm init -y
npm install --save babel-cli
npm install --save-dev babel-eslint babel-plugin-transform-decorators-legacy babel-polyfill babel-preset-env babel-register eslint eslint-plugin-node

4. Добавьте в проект файл .babelrc со следующими настройками:

{
  "presets": ["env"],
  "plugins": ["transform-decorators-legacy"]
}

Дополнительное примечание: если вы используете VSCode в качестве редактора, перейдите в «Настройки» и включите экспериментальные декораторы, чтобы все предупреждения исчезли.

5. Чтобы запустить образец кода, добавьте следующую цель запуска в package.json:

"scripts": {
    "start": "babel-node yourdecoratedcode.js --require babel-polyfill"
  },

Пример стандартного журнала

Затем я посмотрю на широко распространенный @log пример и позже немного его подправлю. Это план ванильного декоратора, вариации которого можно найти во множестве.

Комментарии должны прояснить, что происходит. Функция log - это декоратор, который обертывает метод класса, следующий за аннотацией декоратора @log. Чтобы использовать его, метод класса аннотируется:

Вывод консоли, показанный внизу как комментарий, взят из строки 15 предыдущего листинга.

Ведение журнала с именами параметров

Немного покопавшись, я смог найти примеры кода, которые иллюстрируют способы получения имен параметров из сигнатуры метода. Теперь позвольте декоратору вывести не только значения параметров, но и их имена:

Добавление синтетических параметров

Фактически вы не ограничены предоставленными аргументами, но можете вывести значения параметров из декоратора, передав их в обернутый метод. Это может показаться немного безумным, но я нашел применение этой функции в проекте, над которым работаю.

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

Этот декоратор передаст в качестве аргументов исходной функции все, что находится в MyClass.newStuff.isWombat and MyClass.newStuff.sugar во время вызова функции:

И на выходе ...

{ isWombat: true,
  sugar: [ 'in the morning', 'in the evening', 'at suppertime' ] }
{ isWombat: true,
  sugar: [ 'You are my candy, girl', 'and you keep me wanting you' ] }

Ну вот и все. Репозиторий кода можно найти здесь.