Декоратор — прием программирования, который позволяет взять существующую функцию и изменить/расширить ее поведение.
Декоратор получает функцию и возвращает обертку, которая модифицирует (декорирует) ее поведение, оставляя синтаксис вызова тем же.
Пример декоратора
Например, у нас есть функция 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)