搜索

[Javascript] Decorators in JavaScript


发布时间: 2022-11-24 17:45:01    浏览次数:8 次

First, what is 'High Order function', basic just a function, inside the function return another fuction.

// High order fucntion

function fn() {
  return function(){
    
  }
}

 

For example:

function compose(a, b) {
  return function(c){
    return a(b(c));
  }
}

function addTwo(val){
  return val + 2;
}

function tiemsTwo(val){
  return val * 2;
}

const val = compose(addTwo, tiemsTwo)(50);
console.info(val); // 102

 

Decorators is a subset of high order fucntion:

function fluent(fn){
  return function(...args){
    fn.apply(this, args);
    return this;
  }
}

function Person(){}

Person.prototype.setName = fluent(function(firstName, lastName){
  this.firstName = firstName;
  this.lastName = lastName;
})

Person.prototype.getName = fluent(function(){
  console.log(this.firstName + ' ' + this.lastName);
})

var p = new Person();

console.log( p.setName('John', 'Kent').getName());

In this code, 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.firstName, this.lastName);
  }
}

We have no way to wrap setName and getName fucntion in fluent(). So that's way decorator comes in.

 

To use decorator to descorate a function in class:

function decorate(target, keys, descriptor){
  var fn = descriptor.value;
  
  // Overwrite the value, which in this case is function
  descriptor.value = function(...args){
    fn.apply(target, args);
    return target;
  }
}

class Person {
  
  @decorate
  setName(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
  
  @decorate
  getName(){
    console.log(this.firstName, this.lastName);
  }
}

const p = new Person();
console.log(p.setName("Wan", "Zhentian").getName());

 

And it would be nice to reuse the fluent function:

function fluent(fn){
  return function(...args){
    fn.apply(this, args);
    return this;
  }
}

So we can do:

function fluent(fn){
  return function(...args){
    fn.apply(this, args);
    return this;
  }
}


function decorateWith(fn){
  return (target, keys, descriptor) => {
    // fn here refers to setName or getName
    // fn should be call with in target context, which means Person{}
    // the second argument in call() is function to be 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 = new Person(); 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,资源类别:文本, 浏览次数:8 次, 文件大小:-- , 由本站蜘蛛搜索收录2022-11-24 05:45:01。此页面由程序自动采集,只作交流和学习使用,本站不储存任何资源文件,如有侵权内容请联系我们举报删除, 感谢您对本站的支持。 原文链接:https://www.cnblogs.com/Answer1215/p/5582623.html