Decorator: A special type of declaration that can be attached to a class declaration, method, attribute, or parameter to modify the behavior of a class

A decorator is a method that can be injected into classes, methods, and property parameters to extend the functionality of classes, properties, methods, and parameters.

Common decorators are class decorators, attribute decorators, method decorators, and parameter decorators

Decorator written: ordinary decorator (can not be sent), decorator factory (can be sent)

Decorators have been one of js’s biggest achievements over the past few years and have become a standard feature of Es7

Decorator written: ordinary decorator (can not be sent), decorator factory (can be sent)

  • Common decorator (unable to pass parameters)
function logClass(target:any){
// Target gets an HttpClient
// The methods and attributes of a class can be extended without modifying the class
    target.prototype.apiUrl = 'Dynamically extended Properties'
}
// Next to the class declaration
@logClass
class HttpClient{
    constructor(){}
    getData(){}}let http:any=new HttpClient();
console.log(http.apiUrl) // Dynamically extended properties. Methods can also be extendedCopy the code
  • Decorator factory (passable) use more
function logClass(params:string){
    return function(target:any){
        // The methods and attributes of a class can be extended without modifying the class
        params.prototype.apiUrl = params
    }
}
@logClass('Dynamically extended Properties')
class HttpClient{
    constructor(){}
    getData(){}}let http:any=new HttpClient();
console.log(http.apiUrl) // Dynamically extended properties. Methods can also be extendedCopy the code

Class decorator

Class decorators are declared (immediately before the class declaration), applied to class constructors, and can be used to monitor, modify, or replace the class definition. They can extend the methods and properties of a class without modifying the class.

Class decorators can also overload constructors and methods and attributes.

A class decorator expression is called at run time as a function, with the constructor of the class as its only argument.

You can modify the current function functionality of a class, as well as replace constructors, properties, and methods

function logClass(target:any){
// If the class decorator returns a value, it replaces the class declaration with the provided constructor.
    return class extends target{
        apiUrl: any = 'I'm the modified data.'
        getData(){
            this.apiUrl=this.apiUrl+The '-'
            console.log(this.apiUrl)
        }
    }
}
@logClass
class HttpClient{
    public apiUrl:string | undefined;
    constructor(){
        this.apiURL = I am the apiUrl inside the constructor' } getData(){} } let http:any=new HttpClient(); Console.log (http.apiurl) // I am the modified data http.getData() // I am the modified data --Copy the code

Attribute decorator

The property decorator expression is called as a function at run time, passing in the following two arguments:

  1. Constructor of the class for static members and prototype object for instance members
  2. Name of member
function logClass(target:any){
// Target gets an HttpClient
// The methods and attributes of a class can be extended without modifying the class
    target.prototype.apiUrl = 'Dynamically extended Properties'
}
function logProperty(params:any){
    // Two parameters
    return function(target:any,attr:any){
        console.log(target) // Prototype objects
        console.log(attr) //apiUrltarget[attr] = params; }}// Next to the class declaration, do not add a semicolon
@logClass
class HttpClient{
    // Close the property without a semicolon
    @logProperty('http://test.com')
    public apiUrl: any | undefined;
    constructor(){}
    getData(){
        console.log(this.url)
    }
}
let http:any=new HttpClient();
console.log(http.apiUrl)  // http://test.com
Copy the code

Method decorator

It is applied to method property descriptions and can be used to monitor, modify, or replace method definitions. The method decorator passes the following three arguments at runtime:

  1. Constructor of the class for static members and prototype object for instance members
  2. Name of member
  3. Attribute descriptor for a member
function get(params:any){
    return function(target:any,methodName:any,desc:any){
        console.log(params)  //http://test.com
         console.log(methodName)  //getData
         console.log(desc)  //{writable:true... }
         // Extend attributes
         target.apiUrl = params
         // Extend the method
         target.run=function(){
             console.log('run')}Extension properties and methods have the same functionality as class decorators. You can also modify methodsYou need to modify desc.value, which is the decorated method// Requirement: Modify the decorator method by changing all arguments passed in the decorator method to string
         1.Save the current methodvar oldMethod = desc.value
         2.Convert each item in args to string desc.value=function(. args:any[]){
             args = args.map((item) = >{
                 return StringReplace (item)})console.log(args) // ['123',' I am a string ']
             // The old method is replaced without the following sentence
             // Change the old method
             oldMethod.apply(this,args)  // when http.getData(1213,' I'm a string ') is called}}}class HttpClient{
    public url: any | undefined;
    constructor(){}
    @get('http://test.com')
    getData(){
        console.log('I'm a method in getData')}}let http:any=new HttpClient();
console.log(http.apiUrl)  // http://test.com
http.run() //run
http.getData(1213.'I'm a string')
Copy the code

Method parameter decorator

The parameter decorator expression is called as a function at run time. You can use the parameter decorator to add some element data to the class’s prototype, passing in the following three parameters:

  1. Constructor of the class for static members and prototype object for instance members
  2. Method name
  3. The index of a parameter in the function argument list
function logParams(params:any){
    return function(target:any,methodName:any,paramsIndex:any){
        console.log(params)  //http://test.com
         console.log(methodName)  //getData
         console.log(paramsIndex)  / / 0
         // Add some element data to the class prototype, and add some elements to target
         target.apiUrl = params
    }
}

class HttpClient{
    public url: any | undefined;
    constructor(){}
    getData(@logParams('http://test.com') uid:any)){
        console.log(uid) / / 123}}let http:any=new HttpClient();
http.getData(123)
console.log(http.apiUrl)  // http://test.com
Copy the code

The method parameter decorator is used sparingly, and the class decorator will do the trick, so there is no need to use it

Decorator execution order

  • Property decorator method decorator Method parameter decorator class decorator
  • If you have more than one of the same decorators, the later ones are executed first, such as method decorators and class decorators, which are executed from back to front

As with generics, you don’t need decorators for small projects, but you should be able to read someone else’s frame.