A decorator is a special type of declaration that can be attached to a class declaration, method, accessor, property, or parameter. The decorator uses the form @expression. Expression must be evaluated as a function, which is called at runtime with the decorated life information passed in as an argument.
For example, to have an @fn decorator, you define a function
function fn(target){
// do somethinng.....
}
Copy the code
You can decorate some object with some @ method name and then return a wrapped object, you can decorate some object, class, object, method, etc
1. Decoration factory
A decorator factory function is a simple function that returns an expression to be called by the decorator at run time
function color (value: string) { // Decorator factory
return function (target) { / / a decorator
//do something target and value}}Copy the code
2. Decorator combination
Multiple decorators can be applied to the same declaration. Step A evaluates the decorator expression B from top to bottom, and the result is treated as A function and called from bottom to top
If the decorator factory is used, the result is that the decorator factory function is called from top to bottom, and the decorator factory function is called from bottom to top
function f ( ) {
console.log (' f () : evaluated ')return function (target, value){
console.log (' f () : called ')}}function g ( ) {
console.log (' g () : evaluated ')return function (target, value){
console.log(' g(): called ')}} Class c {@f() @g()method()F (): Evaluated G (): Evaluated G (): called f(): called f(): calledCopy the code
3. Decorator evaluation
Decorator evaluation order on different declarations in a class… slightly
4, Class decorator:
Class decorators are declared before class declarations. Class decorators are used by class constructors to modify or replace class definitions.
A class decorator expression is called at run time as a function, with the constructor of the class as its only argument. The first function argument to the decorator is the target class to decorate. For example, the class constructor is the only argument to fn.
@fn
class newFN{
//do something...
}
Copy the code
If the class decorator returns a value, it replaces the class declaration with the provided constructor class.
Simple decorator
1, the decorator function// The decorator function
const classDecorator = (target: { isShow: boolean; }) = > {
target.isShow = false;
}
//class constructor
@classDecorator
class Mine extends Component{
isShow: string; / / declare
constructor(){
super()}componentDidMount(){
//do something...
}
render(){
return (
<div>My page</div>)}}console.log(Mine.isShow) // False decorator pass Boolean
export default Mine;
Copy the code
// A function can be wrapped around a function. It's the decorator factory
const classDecorator = (flag: boolean) = > { //flag is the argument passed in for the call decorator
return function(target: { isShow: boolean; }) { //target is the constructor class that uses the decorator
target.isShow = flag;
}
}
@classDecorator(true)
class Mine extends Component{
isShow:string;
}
console.log(Mine.isShow) //true the flag passed by the decorator
Copy the code
Overloaded constructor
/ * * 1, declared in a class constructor is not the assignment, the decorator function of variable assignment, and ultimately a decorator () function returns the value of 2, declared in a class constructor and the assignment, the decorator function of variable assignment, and ultimately a decorator () function returns the value of 3, declared in a class constructor and the assignment, in a decorator function variable assignment, The final value returned by the constructor is **/
const classDecorator = (constructor) = > {
return class extends constructor {
newPropoty = "new propoty"
hello = "hello"
}
}
@classDecorator
class Greeter {
propoty = "propoty";
hello: string;
constructor(m: string){
this.hello = m
}
}
console.log(new Greeter('hello2')) //
Copy the code
The previous example added a static attribute to a class. If you want to add instance attributes, you can do so through the prototype object of the target class.
export const classDecorator = (. message) = > {
return function(target) {
Object.assign(target.prototype, ... message) } }const Foo = {
foo() { console.log('foo')}}; @classDecorator(Foo)class Mine extends Component{... }console.log(new Mine().foo()) //foo Prints inside the foo object
// Add the object Foo to the Mine instance using the classDecorator decorator.
Copy the code
5. Method decorator
The method decorator is called as a function at run time, passing in three arguments
1. The prototype object of class,
2. The name of the property to decorate
3. The description object of this property
/ / a decorator
export const decoratorFn = (target, name, descriptor) = >{
descriptor.isShow = true;
return descriptor;
}
class Mine extends Component {
gretting: string;
constructor(m){
super(m)
this.gretting = m;
}
// Method decorator
@decoratorFn
great(){
return 'hello,' + 'this.gretting'}}Copy the code
When the @decoratorFn is called, the isShow value of the property Descriptor is modified