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!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



async is es7. async and await are new additions to ES7 and are solutions for asynchronous operations; async/await can be said to be syntactic sugar for co modules and generator functions, solving js asynchronous code with clearer semantics. As the name suggests, async means "asynchronous". Async is used to declare that a function is asynchronous; there is a strict rule between async and await. Both cannot be separated from each other, and await can only be written in async functions.

In ES6, you can use the reverse() method of the array object to achieve array reversal. This method is used to reverse the order of the elements in the array, putting the last element first and the first element last. The syntax "array.reverse()". The reverse() method will modify the original array. If you do not want to modify it, you need to use it with the expansion operator "...", and the syntax is "[...array].reverse()".

For browser compatibility. As a new specification for JS, ES6 adds a lot of new syntax and API. However, modern browsers do not have high support for the new features of ES6, so ES6 code needs to be converted to ES5 code. In the WeChat web developer tools, babel is used by default to convert the developer's ES6 syntax code into ES5 code that is well supported by all three terminals, helping developers solve development problems caused by different environments; only in the project Just configure and check the "ES6 to ES5" option.

Steps: 1. Convert the two arrays to set types respectively, with the syntax "newA=new Set(a);newB=new Set(b);"; 2. Use has() and filter() to find the difference set, with the syntax " new Set([...newA].filter(x =>!newB.has(x)))", the difference set elements will be included in a set collection and returned; 3. Use Array.from to convert the set into an array Type, syntax "Array.from(collection)".

In es5, you can use the for statement and indexOf() function to achieve array deduplication. The syntax "for(i=0;i<array length;i++){a=newArr.indexOf(arr[i]);if(a== -1){...}}". In es6, you can use the spread operator, Array.from() and Set to remove duplication; you need to first convert the array into a Set object to remove duplication, and then use the spread operator or the Array.from() function to convert the Set object back to an array. Just group.

How do decorators and context managers work in Python? In Python, decorators and context managers are two very useful concepts and features. They are all designed to simplify code, increase code readability, and facilitate code reuse. 1. Decorator A decorator is a special function in Python that is used to modify the behavior of a function. It allows us to wrap or extend the original function without modifying it. Decorators are widely used in many Python frameworks and libraries, such as Flask, Dj

This is our third article to teach you step by step how to implement a Python timer. The first two articles: teach you step by step how to implement a Python timer, and use context managers to extend Python timers, making our Timer class convenient to use, beautiful and practical. But we are not satisfied with this, there is still a use case that can simplify it further. Suppose we need to track the time spent in a given function in our code base. With a context manager, you basically have two different options: 1. Use Timer every time you call a function: with Timer("some_name"): do_something() When we are in

In es6, the temporary dead zone is a syntax error, which refers to the let and const commands that make the block form a closed scope. Within a code block, before a variable is declared using the let/const command, the variable is unavailable and belongs to the variable's "dead zone" before the variable is declared; this is syntactically called a "temporary dead zone". ES6 stipulates that variable promotion does not occur in temporary dead zones and let and const statements, mainly to reduce runtime errors and prevent the variable from being used before it is declared, resulting in unexpected behavior.
