How much do you know about Decorator?

Keywords: Javascript Front-end

preface

Do you really know about decorators? I believe that developers who have used decorators must love some of its features. Both react, vue and angular can be supported through babel. Of course, there are some encapsulated third-party decorator libraries, which can realize some powerful functions after reference. Let's have a brief look.

What is a decorator?

Decorator is a function designed to modify a class and its members.
Javascript The decorator is still in draft, and there is no environment that directly supports this syntax, but Babel Its syntax conversion is already supported.
stay TypeScript Li has also been supported as an experimental feature.
stay Angular It is also widely used in, and there are many built-in decorators.
In fact, it is an implementation of the decorator pattern often said in the design pattern

Decorator mode refers to dynamically extending the function of an object without changing the original class file or using inheritance,
A design pattern that adds additional properties to an object.

Why use a decorator?

The decorator has the characteristics of convenience, high efficiency and stronger semantics.
The rational use of decorators can greatly improve the development efficiency, encapsulate and refine the logic code of Non internal functions
 Can help us quickly complete repetitive work.

Application and example of Decorator decorator

case 1: basic usage of modifier class

Add a decorator to the class, and automatically pass the class as the first parameter to the decorator.

case 2: decorate classes and customize parameters

If you feel that a parameter is not enough, you can encapsulate another layer of function in the outer layer of the decorator function. Not only decorators, but also specified parameters can be passed to methods such as computed and getter by using the characteristics of closures in Vue.

When decorating the properties of a class, the decorator will intelligently decorate the prototype

  • The first parameter is the target element to be decorated,
  • The second parameter is the attribute name,
  • The third parameter is the description object of the attribute

The decorator changes the behavior of the class when the code is compiled, not at run time.

Case 3 application of nesting multiple decorators

If multiple decorators are passed, the external functions of all decorators are executed in sequence. After execution, use reduce to recursively execute the obtained interior decorator function in reverse order.

case4 implements multi inheritance of classes

In js, there is no direct syntax for class to realize multiple inheritance. If you want to realize multiple inheritance, you can only use mixin or indirect means such as getOwnPropertyNames traversal. For example:

class C extends A, B {}        // Error
class C extends A extends B {} // Error
Mixin Method implementation
class A{}
function Mixin ( BaseClass ) {
	return class extends BaseClass
	{
		mixin(){ console.log('This is the method of a mixed inherited class, which generates a new expression class') }
	}
}
class C extends Mixin(A){}
new C().mixin() // This is the method of a mixed inherited class, which generates a new expression class

// Implementation of getOwnPropertyNames
class C extend B {} 
for (let key of Object.getOwnPropertyNames(A.prototype)) {
 if (key === 'constructor') continue 
Object.defineProperty(C.prototype, key, Object.getOwnPropertyDescriptor(A.prototype, key)) 
}

However, with the decorator, developers do not need to pay attention to the above specific implementation,
Through @ Decorator, you can save a lot of tedious steps to use the Decorator

case5 other commonly used simple decorators

@readonly decorator

Make properties read-only
class Person{
@readonly // Make the property read-only.
age() {
}
}
function readonly(target, name, descriptor){
    // The original value of the descriptor object is as follows
  // {
  //   value: specifiedFunction,
  //   enumerable: false,
  //   configurable: true,
  //   writable: true
  // };
  descriptor.writable = false;
  return descriptor;
}
readonly(Person.prototype, 'name', descriptor)

@Getexcetetime decorator,

Gets the time from the start time to the end of the execution of a function
 This was needed in the past
class Person{
something1(){
let start = Date.now()
// do something...
let end = Date.now()
console.log('Execution time:',end-start)
}
something2(){
let start = Date.now()
// do something...
let end = Date.now()
console.log('Execution time:',end-start)
}
}
Using the decorator,Separate timing from business
class Person{
@getExcuteTime
something1(){
// do something...
}
@getExcuteTime
something2(){
// do something...
}
}

@log decorator

We don't want logs to be mixed with business, so we can avoid this problem by using modifiers
class Person{
@log('Start the first step')
step1() {
// do something...
// There is no need to write the logic of printing in the function
}
@log('Start the second step')
step2() {
// do something...
}
}

function log(value) {
    return function (target, name, descriptor) {
        // More detailed information can be printed here according to the parameters
        console.log(value)
    }
}

There are also decorators such as login (don't repeat the logic of whether to log in) and aixos, which need to be implemented according to our specific needs.

other

The decorator used in vue project is an officially provided component Decorator

core-decorators.js provides some Common decorator methods

summary

In general, decorators are simple and easy to use. The rational use of decorators can improve our development efficiency, make the code more readable, easier to maintain and more aggregate functions.

In addition, if you find something unreasonable or wrong in reading, you are welcome to leave a message for correction. Thank you very much!

If you feel helpful, you might as well praise, pay attention and support. Thanks again!

Author: tager
Link: https://juejin.cn/post/7020406094904164383
Source: rare earth Nuggets
The copyright belongs to the author. For commercial reprint, please contact the author for authorization, and for non-commercial reprint, please indicate the source.

Posted by Fyorl on Sat, 23 Oct 2021 01:06:39 -0700