The idea of decorators came about because of the nestJS used in the BFF layer of the company’s project, which uses a lot of decorators. This writing method is concise and clear, and it is also easy to maintain in the later period.

The benefits of decorators

  1. A good decorator is a code comment;
  2. Help code decoupling;
  3. Improve code reuse;
  4. Code is cleaner and easier to read;

The use of decorators

Decorators can currently be thought of as a modification or modification of the class. The decorator itself is a function that can precede class, class method, and class method parameter definitions.

function testD(target){
	return target.test = true
}

@testD
class Test {}

console.log(Test.test) 			// true
Copy the code

An addition to an internal class attribute is done through the decorator.

Decoration class

The code above is a decoration for the class, taking a target argument that is the Test class itself.

If you want to pass a parameter, you can do this:

function testD(params){
	return function(target){
    	return target.test = params
    }
}

@testD(true)
class Test{}
Copy the code

The above code adds static properties to classes. If you want to add instance properties, consider adding them to test.Prototype.

Methods that decorate classes

class Person {
    @nonenumerable
    get kidCount() { return this.children.length; }}function nonenumerable(target, name, descriptor) {
    descriptor.enumerable = false;
    return descriptor;
}
Copy the code

Decorator class methods support three parameters. The first parameter is the prototype object of the class, the second parameter is the name of the property to be decorated, and the third parameter is the description object of the property. The above decorator makes the property non-traversal.

Decorates the parameters of the class’s methods

The function argument decorator accepts three arguments:

  1. The prototype of the class
  2. The name of the function in which the argument is located
  3. The position of an argument in a function parameter (the number of arguments in the function signature)

The main application scenarios of decoration function parameters are checksum conversion of parameters.

Reflect.metadata

Reflect Metadata When you define a class or a class method, you can set some Metadata. You can retrieve Metadata added to classes and class methods by using Reflect Metadata. Metadata refers to the data used to describe things.

@Reflect.metadata('name'.'zhangsan')
class People{}

const data = Reflect.getMetadata('name', People)
console.log(data) 			//zhangsan
Copy the code

Reflect.metadata is used as a decorator directly above. If you want to implement more complex functions, you can also customize it:

function Name(params){
	return (target) = > {
		Reflect.defineMetadata('name', params, target)
    }
}

@Name('zhangsan')
class People{}

const data = Reflect.getMetadata('name', People)
console.log(data) 			//zhangsan
Copy the code

Use decorators in projects

The decorator is currently in the proposal stage. Babel supports compiling decorators. To use it in your project, install the plugin babel-plugin-transform-decorators-legacy, @babel/plugin-proposal-decorators.

If the ide is vscode, setting. Json configured in “javascript. ImplicitProjectConfig. ExperimentalDecorators” : true

To use reflect. metadata you need to install the reflect-metadata package, if it is a TS project, and configure tsconf.json:

{
  "compilerOptions": {
    "experimentalDecorators": true ,
    "emitDecoratorMetadata": true
  },
}
Copy the code

The latter

Decorators are executed at compile time, not run time. A decorator is a function that is executed at compile time to modify a class.

Why decorators can’t be used for functions: Function promotion exists and classes don’t.

Reference:

Es6.ruanyifeng.com/#docs/decor…

Juejin. Cn/post / 684490…