Home > Article > Web Front-end > How to understand es6 decorators
In es6, the decorator pattern is a design theory that dynamically extends the functions of an object without changing the original class and using inheritance; the essence of the decorator is an ordinary function, used for extension Class attributes and class methods. Advantages of using decorators: 1. The code becomes more readable, and the decorator naming is equivalent to a comment; 2. The original functions can be expanded without changing the original code.
The operating environment of this tutorial: Windows 7 system, ECMAScript version 6, Dell G3 computer.
How to understand Decorator in ES6?
Decorator, that is, decorator, from its name, it is easy for us to think of the decorator pattern
Simply speaking, the decorator pattern is a method that does not change the original Classes and the design theory of dynamically extending object functionality using inheritance.
The same is true for the Decorator function in ES6. Its essence is not a tall structure, it is just an ordinary function used to extend class attributes and class methods
A soldier is defined here. He has no equipment.
class soldier{ }
Define a function to get AK equipment, that is, the decorator
function strong(target){ target.AK = true }
Use the decorator to enhance the soldier
@strong class soldier{ }
At this time, the soldier has Weapon
soldier.AK // true
Although the above code is simple, we can clearly see the two major advantages of using Decorator:
The readability of the code becomes stronger. The decorator naming is equivalent to a comment
Expand the original function without changing the original code
Usage of decorator
Docorator modified objects are the following two types:
Class decoration
Decoration of class attributes
Decoration of class
When decorating the class itself, it can accept one parameter, that is, the class itself
Decompose the decorator behavior so that everyone can have a deeper understanding
@decorator class A {} // 等同于 class A {} A = decorator(A) || A;
The following @testable
is a decorator, and the target is the incoming class, that is MyTestableClass implements adding static attributes to classes
@testable class MyTestableClass { // ... } function testable(target) { target.isTestable = true; } MyTestableClass.isTestable // true
If you want to pass parameters, you can encapsulate a layer of functions outside the decorator
function testable(isTestable) { return function(target) { target.isTestable = isTestable; } } @testable(true) class MyTestableClass {} MyTestableClass.isTestable // true @testable(false) class MyClass {} MyClass.isTestable // false
Decoration of class attributes
When decorating class attributes, it can accept three parameters:
Prototype object of the class
Required Decorated attribute name
Description object of decorated attribute name
First define a readonly decorator
function readonly(target, name, descriptor){ descriptor.writable = false; // 将可写属性设为false return descriptor; }
Use readonly decoration The name method of the class
class Person { @readonly name() { return `${this.first} ${this.last}` } }
is equivalent to the following call
readonly(Person.prototype, 'name', descriptor);
If a method has multiple decorators, just like an onion, first enter from the outside to the inside, and then execute from the inside to the outside
function dec(id){ console.log('evaluated', id); return (target, property, descriptor) =>console.log('executed', id); } class Example { @dec(1) @dec(2) method(){} } // evaluated 1 // evaluated 2 // executed 2 // executed 1
The outer decorator @dec(1) enters first, but the inner decorator @dec(2) executes first
Note
Decorators cannot be used to decorate functions because there are variable declarations in the function.
var counter = 0; var add = function () { counter++; }; @add function foo() { }
During the compilation phase, it becomes the following
var counter; var add; @add function foo() { } counter = 0; add = function () { counter++; };
The intention is that counter is equal to 1 after execution. But in fact the result is that counter is equal to 0
Usage scenarios of decorator
Based on the powerful function of Decorator, we can complete various scenarios Requirements, here is a brief list of several:
When using react-redux, if it is written in the following form, it is both unsightly and troublesome
class MyReactComponent extends React.Component {} export default connect(mapStateToProps, mapDispatchToProps)(MyReactComponent);
It becomes much simpler through the decorator
@connect(mapStateToProps, mapDispatchToProps) export default class MyReactComponent extends React.Component {}
Mixins can also be written as decorators to make their use more concise
function mixins(...list) { return function (target) { Object.assign(target.prototype, ...list); }; } // 使用 const Foo = { foo() { console.log('foo') } }; @mixins(Foo) class MyClass {} let obj = new MyClass(); obj.foo() // "foo"
Let’s talk about several common decorators in core-decorators.js
@antobind
The autobind decorator makes the this object in the method bind the original object
import { autobind } from 'core-decorators'; class Person { @autobind getPerson() { return this; } } let person = new Person(); let getPerson = person.getPerson; getPerson() === person; // true
@readonly
readonly The decorator makes a property or method unwritable
import { readonly } from 'core-decorators'; class Meal { @readonly entree = 'steak'; } var dinner = new Meal(); dinner.entree = 'salmon'; // Cannot assign to read only property 'entree' of [object Object]
@deprecate
The deprecate or deprecated decorator displays a warning on the console indicating that the method will be deprecated
import { deprecate } from 'core-decorators'; class Person { @deprecate facepalm() {} @deprecate('功能废除了') facepalmHard() {} } let person = new Person(); person.facepalm(); // DEPRECATION Person#facepalm: This function will be removed in future versions. person.facepalmHard(); // DEPRECATION Person#facepalmHard: 功能废除了
[Related recommendations: javascript video tutorial, web front-end]
The above is the detailed content of How to understand es6 decorators. For more information, please follow other related articles on the PHP Chinese website!