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