📜 ⬆️ ⬇️

JavaScript Decorators

For a long time I use decorators in JavaScript. Recently I saw a habrotopic about impurities, which prompted me to share my own experience, because the technologies are a bit similar.

What does not suit me in known implementations?


The implementations suggested by the first links in Google do not work the way it does in Python. In many articles, it is proposed to create an object, fill its fields with functions, and make calls decoded through these fields.
The first page has several links that use methods similar to mine,
There are many more implementations, but they are not interesting to me.
I will tell the most correct from my point of view.

Normal decorator


So what is a decorator?
A decorator is a function that adds functionality to the function's argument.

Python example:
def superfunc(n=2): print("Megclosure created") def clos(func): print("Megclosure used") def clos1(*args, **kwargs): print("Megclosured function",func.__name__) res = func(*args, **kwargs) return (res**n) return clos1 return clos def a(par): return par+9; b = (superfunc())(a) @superfunc(3) def c(txt): return len(txt)+1 print ( b(1),c("abc"*3)) 

What are we doing here?
We here create a function that creates another function that performs what we need and calls the function being decorated.
')

How will it be on javascript


So, we want to call a function, passing it a function and, possibly, additional parameters, and get the decoded function b, i.e.
 function decorator(){ ..... } ..... function a(){ ...... } ...... var b=decorator(a, arg1, arg2,....., argN); 
.


I will give a piece of code from one of its libraries
 function withVars(f, variables) { var args = Array.prototype.slice.call(arguments, 1);//    ,    ,    return function () {//  f  args,    var p = arguments;//   arguments     ... Array.prototype.push.apply(p, args);//...    p f.apply(this, p);//   f   this   p } }; 

And application:
 function a(){ var str =""; for(var i=0;i<arguments.length;i++){ str+=arguments[i]+" "; } alert(str); } a(1,2,4,5,"six");//1 2 3 4 5 six var b=withVars(a,4,8,15,16,23,42); b(1,2,4,5,"six");//1 2 3 4 5 six 4 8 15 16 23 42 

As a result, in several lines of code we get a powerful effect.
With a slight movement of the hand, the function can be remade so that the parameter is added to the beginning. To do this, simply replace
 Array.prototype.push.apply(p, args); f.apply(this, p); 

on
 Array.prototype.push.apply(args,p); f.apply(this, args); 
.

Possible uses





What to read


JavaScript.ru - Closures
arguments - MDN
apply - MDN

PS Thank you UFO for an invite.

UPD1: Added several uses.
UPD2: fixed a little code

Source: https://habr.com/ru/post/132682/


All Articles