A decorator

A decorator is essentially a function that works only on class, static, and dynamic members of a class. The semantic structure is clear, which can provide additional features to the class without destroying the class cohesion. Decorators are translated into corresponding expression statements at compile time.

On the class

@decorator
class Person {}

/ / equivalent to
class Person {};
Person = decorator(Person) || Person;


Copy the code

Applies to properties/methods

class Person {
	@readonly
	name(){}}// In other words, the return value of the decorator only acts as a function of 'Descriptor', ignoring properties that are not 'descriptor'
Object.defineProperty(Person.prototype, 'name',  readonly(Person.prototype, 'name'.Object.getOwnPropertyDescriptor(Person, 'name')) || Object.getOwnPropertyDescriptor(Person, 'name'));
Copy the code

Decorators can accept arguments


@decorator(true)
class Person {}

/ / equivalent to
class Person {};
Person = decorator(true)(Person) || Person;
Copy the code

Multiple decorators

// apply to class
@dec(12)
@decorator(true)
class Person {}

/ / equivalent to
class Person {};

// Execute from outside to inside
const decFn = dec(12);
const decoratorFn = decorator(true)

// Execute from inside out
Person = decoratorFn(Person) || Person;
Person = decFn(Person) || Person;
Copy the code
// applies to properties/methods
class Person {
	@readonly()
	@override()
	name(){}}/ / equivalent to
class Person {};

// Execute from outside to inside
const read = readonly();
const over = override()

// Execute from inside out
let descriptor = Object.getOwnPropertyDescriptor(Person, 'name');
Object.defineProperty(Person.prototype, 'name',  over(Person.prototype, 'name', descriptor) || descriptor);
descriptor = Object.getOwnPropertyDescriptor(Person, 'name');
Object.defineProperty(Person.prototype, 'name',  read(Person.prototype, 'name', descriptor) || descriptor);
Copy the code

Preparation before use

Since decorators are currently a proposal, using the decorator syntax requires setting up Babel or typescript configurations.

  • Babel need to install the syntax support plug-in [Babel – plugin – syntax – decorators] (https://www.npmjs.com/package/babel-plugin-syntax-decorators)

  • Typescript requires tsconfig.json configuration

    {
        "compilerOptions": {
            "target": "ES5"."experimentalDecorators": true.// Configure the decorator syntax}}Copy the code

Third-party libraries

Core-decorators. js, provides several common decorators, some of which are as follows:

* * : - * * @ autobind ` this ` binding - * *, * * @ readonly attribute read-only - * * * * @ override: cover the original method, the * * * * @ deprecate @ deprecated (* * * *) : scrap logoCopy the code

Attribute description objectinstructions

Each attribute has a corresponding attribute description object, according to the different attributes can be divided into data attribute or access attribute, the corresponding attribute description object structure is also different. By modifying attribute description Object through Object.defineProperty, data attribute can be converted to access attribute.

configurable(have) enumerable(have) value ediatble get set
Can IT be modified?Attribute description object(falseThe assignment expression can still be modifiedvalue) Whether a property can be enumerated The value of the attribute Controls whether a value can be modified by an assignment expression Called when property is read Called when the property is assigned
Data attributes There are There are There are There are There is no There is no
Access the properties There are There are There is no There is no There are There are