Декоратор — прием программирования, который позволяет взять существующую функцию и изменить/расширить ее поведение.
Декоратор получает функцию и возвращает обертку, которая модифицирует (декорирует) ее поведение, оставляя синтаксис вызова тем же.
Пример декоратора
Например, у нас есть функция sum(a,b):
Создадим декоратор doublingDecorator, который меняет поведение, увеличивая результат работы функции в два раза:
01 |
function doublingDecorator(f) { |
03 |
return 2*f.apply(this, arguments); |
13 |
sum = doublingDecorator(sum); |
Декоратор doublingDecorator создает анонимную функцию-обертку, которая в строке (*) вызывает fпри помощи apply с тем же контекстом this и аргументами arguments, а затем удваивает результат.
Этот декоратор можно применить два раза:
1 |
sum = doublingDecorator(sum); |
2 |
sum = doublingDecorator(sum); |
Контекст this в sum никак не используется, поэтому можно бы было вызватьf.apply(null, arguments).
Еще пример
Посмотрим еще пример. Предположим, у нас есть функция isAdmin(), которая возвращает true, если у посетителя есть права администратора.
Можно создать универсальный декоратор, который добавляет в функцию проверку прав:
Например, создадим декоратор checkPermissionDecorator(f). Он будет возвращать обертку, которая передает вызов f в том случае, если у посетителя достаточно прав:
1 |
function checkPermissionDecorator(f) { |
4 |
return f.apply(this, arguments); |
6 |
alert('Недостаточно прав'); |
Использование декоратора:
1 |
function save() { ... } |
3 |
save = checkPermissionDecorator(save); |
Декораторы можно использовать в любых комбинациях:
sum = checkPermissionDecorator(sum); |
sum = doublingDecorator(sum); |
Зачем декораторы?
Декораторы меняют поведение функции прозрачным образом.
- Декораторы можно повторно использовать. Об этом говорит сайт https://intellect.icu . Например,
doublingDecorator можно применить не только к sum, но и к multiply, divide. Декоратор для проверки прав можно применить к любой функции.
- Несколько декораторов можно скомбинировать. Это придает дополнительную гибкость коду.
Примеры использования есть в задачах.
Задачи
Важность: 5
Решение
[Открыть задачу в новом окне]
Важность: 3
Решение аналогично задаче Логирующий декоратор (1 аргумент), разница в том, что в лог вместо одного аргумента идет весь объект arguments.
Для передачи вызова с произвольным количеством аргументов используемf.apply(this, arguments).
[Открыть задачу в новом окне]
Важность: 5
Запоминать результаты вызова функции будем в замыкании, в объектеcache: { ключ:значение }.
Обратите внимание: проверка на наличие уже подсчитанного значения выглядит так:if (x in cache). Менее универсально можно проверить так: if (cache[x]), это если мы точно знаем, что cache[x] никогда не будет false, 0 и т.п.
Комментарии
Оставить комментарий
Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)
Термины: Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)