First, what's ' High Order function ', basic just a function, inside the function return another fuction.
// High order Fucntion function fn () { returnfunction() { }}
For example:
function Compose (A, b) { returnfunction(c) { return A (b (c));} } function AddTwo (val) { return val + 2;} function Tiemstwo (val) { return val * 2= Compose (AddTwo, tiemstwo); Console.info (Val); 102
Decorators is a subset of high order Fucntion:
functionFluent (FN) {return function(... args) {fn.apply ( This, args); return This; }}functionPerson () {}person.prototype.setname= Fluent (function(FirstName, lastName) { This. FirstName =FirstName; This. LastName =LastName;}) Person.prototype.getName= Fluent (function() {Console.log ( This. FirstName + "+ This. lastName);})varp =NewPerson (); Console.log (P.setname (' John ', ' Kent '). GetName ());
In this code, the fluent actually decorate person class, make it chainable.
But in ES6:
class Person { setName (F, l) { this. FirstName = f; this. lastName = l; } GetName () { Console.log (this. lastName); }}
We have no-to-wrap setName and GetName fucntion in fluent (). So that's the decorator comes in.
To use decorator to descorate a function in class:
functiondecorate (target, keys, descriptor) {varfn =Descriptor.value; //Overwrite the value, which in this case is functionDescriptor.value =function(... args) {fn.apply (target, args); returnTarget; }}class person {@decorate setName (firstName, lastName) { This. FirstName =FirstName; This. LastName =LastName; } @decorate GetName () {Console.log ( This. FirstName, This. LastName); }}const P=NewPerson (); Console.log (P.setname ("Wan", "Zhentian"). GetName ());
And it would is nice to reuse the fluent function:
function Fluent (FN) { returnfunction(... args) { fn.apply (this , args); return This ; }}
So we can do:
functionFluent (FN) {return function(... args) {fn.apply ( This, args); return This; }}functionDecoratewith (FN) {return(Target, keys, descriptor) = { //fn here refers to SetName or GetName //FN should is call with in target context, which means person{} //The second argument in call () are function to being passed into fluent () function
Descriptor.value =Fn.call (target, descriptor.value); }}class Person {@decorateWith (fluent) setName (FirstName, lastName) { This. FirstName =FirstName; This. LastName =LastName; } @decorateWith (Fluent) GetName () {Console.log ( This. FirstName, This. LastName); }}const P=NewPerson (); Console.log (P.setname ("Wan", "Zhentian"). GetName ());
[Note]: Call (context, arguement, arguement, ...); Here arguement is Sinlge value
Apply (context, arguements): Here arguements is array
[Javascript] Decorators in JavaScript