Decorator is a programming technique that allows you to take an existing function and change / expand its behavior.
The decorator gets the function and returns a wrapper that modifies ( decorates ) its behavior, leaving the call syntax the same.
Decorator example
For example, we have a function sum(a,b)
:
Create a doublingDecorator
decorator, which changes the behavior, increasing the result of the function two times:
01 | function doublingDecorator(f) { |
03 | return 2*f.apply( this , arguments); |
13 | sum = doublingDecorator(sum); |
The doublingDecorator
decorator creates an anonymous wrapper function that, in line (*)
calls f
using apply with the same this
context and arguments arguments
, and then doubles the result.
This decorator can be applied twice:
1 | sum = doublingDecorator(sum); |
2 | sum = doublingDecorator(sum); |
The context of this
in sum
is not used at all, so one could call f.apply(null, arguments)
.
Another example
Let's see another example. Suppose we have an isAdmin()
function that returns true
if the visitor has administrator rights.
You can create a universal decorator that adds rights verification to the function:
For example, create a decorator checkPermissionDecorator(f)
. It will return a wrapper that sends the call to f
if the visitor has enough rights:
1 | function checkPermissionDecorator(f) { |
4 | return f.apply( this , arguments); |
6 | alert( 'Недостаточно прав' ); |
Use Decorator:
1 | function save() { ... } |
3 | save = checkPermissionDecorator(save); |
Decorators can be used in any combination:
sum = checkPermissionDecorator(sum); |
sum = doublingDecorator(sum); |
Why decorators?
Decorators change the behavior of a function in a transparent manner.
- Decorators can be reused. For example,
doublingDecorator
can be applied not only to sum
, but also to multiply
, divide
. Decorator to check the rights can be applied to any function. - Multiple decorators can be combined. This gives additional flexibility to the code.
Examples of use are in tasks.
Tasks
Importance: 5
Decision
[Open task in new window]
Importance: 3
The solution is similar to the task Logging decorator (1 argument), the difference is that the entire arguments
object goes to the log instead of a single arguments
.
To transfer a call with an arbitrary number of arguments, use f.apply(this, arguments)
.
[Open task in new window]
Importance: 5
We will remember the results of the function call in the closure, in the cache: { ключ:значение }
object cache: { ключ:значение }
.
Note: checking for the presence of the already calculated value looks like this: if (x in cache)
. Less universally, you can check this: if (cache[x])
, this is if we know for sure that cache[x]
will never be false
, 0
, etc.
Comments
To leave a comment
Scripting client side JavaScript, jqvery, BackBone
Terms: Scripting client side JavaScript, jqvery, BackBone