In es6, decorators are used to annotate or modify classes and class methods, relying on the "Object.defineProperty" method of ES5, written as "@function name"; the decorator is actually a function, usually put before classes and class methods. Modifiers can be injected into classes, methods, and attribute parameters to extend the functions of classes, attributes, methods, and parameters.
The operating environment of this tutorial: Windows 7 system, ECMAScript version 6, Dell G3 computer.
The Decorator Pattern allows adding new functionality to an existing object without changing its structure. This type of design pattern is a structural pattern, which acts as a wrapper around an existing class.
This mode creates a decoration class to wrap the original class and provide additional functionality while maintaining the integrity of the class method signature.
In ES6, decorator (Decorator) is a class-related syntax used to annotate or modify classes and class method.
A decorator is actually a function, usually placed in front of classes and class methods.
@decorateClass class Example { @decorateMethods method(){} }
Two decorators are used in the above code, among which the @decorateClass() decorator is used in the class itself for Add or modify the functionality of a class; the @decorateMethods() decorator is used on class methods to annotate or modify class methods.
Decorators can only be used for classes and class methods, not functions, because there are functions promote.
Decorators can only be used for classes and class methods. Let’s look at the use of two types of decorators respectively
Class decorator is used to decorate the entire class
target: The class itself is also equivalent to the constructor of the class: Class. prototype.constructor.
@decorateClass class Example { //... } function decorateClass(target) { target.isTestClass = true }
As shown in the above code, the decorator @decorateClass modifies the behavior of the entire Example class and adds a static attribute isTestClass to the Example class. . The decorator is a function. The parameter target in the decorateClass function is the Example class itself, which is also equivalent to the class constructor Example.prototype.constructor.
The decorator implemented above cannot be passed in parameters when used. If you want to pass in parameters when using the decorator, you can encapsulate a layer of functions outside the decorator
@decorateClass(true) class Example { //... } function decorateClass(isTestClass) { return function(target) { target.isTestClass = isTestClass } }
The decorator implemented in the above code can pass parameters when used, so that the behavior of the decorator can be modified according to different scenarios.
In actual development, when React is used in combination with the Redux library, it is often necessary to write it as follows.
class MyReactComponent extends React.Component {} export default connect(mapStateToProps, mapDispatchToProps)(MyReactComponent);
With the decorator, you can rewrite the above code.
@connect(mapStateToProps, mapDispatchToProps) export default class MyReactComponent extends React.Component {}
Class method decorator is used to decorate methods of a class
target:
Class method modified by the decorator It is a static method: target is the constructor of the class
The class method modified by the decorator is an instance method: target is the prototype object of the class
method: the name of the modified class method
descriptor: the attribute descriptor of the modified member
// descriptor对象原来的值如下 { value: specifiedFunction, enumerable: false, configurable: true, writable: true };
class Example { @log instanceMethod() { } @log static staticMethod() { } } function log(target, methodName, descriptor) { const oldValue = descriptor.value; descriptor.value = function() { console.log(`Calling ${name} with`, arguments); return oldValue.apply(this, arguments); }; return descriptor; }
As in the above code, the decorator @log decorates the instance method instanceMethod and the static method staticMethod respectively. The function of the @log decorator is to execute console.log to output the log before performing the original operation.
The decorator implemented above cannot be passed in parameters when used. If you want to use the decorator, you must pass in parameters. , you can encapsulate another layer of functions outside the decorator
class Example { @log(1) instanceMethod() { } @log(2) static staticMethod() { } } function log(id) { return (target, methodName, descriptor) => { const oldValue = descriptor.value; descriptor.value = function() { console.log(`Calling ${name} with`, arguments, `this id is ${id}`); return oldValue.apply(this, arguments); }; return descriptor; } }
The decorator implemented in the above code can pass parameters when used, In this way, the behavior of the decorator can be modified according to different scenarios.
If in a class, a decorator is used to decorate the class and class method at the same time, then the decorator The execution order is: first execute the class method decorator, and then execute the class decorator.
If the same class or the same class method has multiple decorators, it will be like peeling an onion, first entering from the outside to the inside, and then executing from the inside to the outside.
// 类装饰器 function decoratorClass(id){ console.log('decoratorClass evaluated', id); return (target) => { // target 类的构造函数 console.log('target 类的构造函数:',target) console.log('decoratorClass executed', id); } } // 方法装饰器 function decoratorMethods(id){ console.log('decoratorMethods evaluated', id); return (target, property, descriptor) => { // target 代表 // process.nextTick((() => { target.abc = 123 console.log('method target',target) // })) console.log('decoratorMethods executed', id); } } @decoratorClass(1) @decoratorClass(2) class Example { @decoratorMethods(1) @decoratorMethods(2) method(){} } /** 输入日志 **/ // decoratorMethods evaluated 1 // decoratorMethods evaluated 2 // method target Example { abc: 123 } // decoratorMethods executed 2 // method target Example { abc: 123 } // decoratorMethods executed 1 // decoratorClass evaluated 1 // decoratorClass evaluated 2 // target 类的构造函数: [Function: Example] // decoratorClass executed 2 // target 类的构造函数: [Function: Example] // decoratorClass executed 1
如上面代码中,会先执行类方法的装饰器 @decoratorMethods(1) 和 @decoratorMethods(2),执行完后再执行类装饰器 @decoratorClass(1) 和 @decoratorClass(2)
上面代码中的类方法装饰器中,外层装饰器 @decoratorMethods(1) 先进入,但是内层装饰器 @decoratorMethods(2) 先执行。类装饰器同理。
function log(target, name, descriptor) { var oldValue = descriptor.value; descriptor.value = function () { console.log(`Calling "${name}" with`, arguments); return oldValue.apply(null, arguments); } return descriptor; } // 日志应用 class Maths { @log add(a, b) { return a + b; } } const math = new Maths(); // passed parameters should get logged now math.add(2, 4);
【相关推荐:javascript视频教程、web前端】
The above is the detailed content of What are es6 modifiers used for?. For more information, please follow other related articles on the PHP Chinese website!