Home  >  Article  >  Backend Development  >  Introduction to Decorator and related tutorials

Introduction to Decorator and related tutorials

小云云
小云云Original
2017-12-05 10:11:141430browse

Decorator Introduction

Decorator is a function that can extend a class or method by annotating expressions. Decorator can be applied to any class or property. For example:

@myDecorator class A {} // 作用class

@myDecorator
doSomething() {}  // 作用表达式

Javascript Decorator is still in the ES7 proposal status. For more progress on this feature, you can visit proposal-decorators to view.

Decorator Principle

When it comes to changing the properties or methods of an object, everyone will definitely think of the Object.defineProperty(obj, prop, descriptor) method. Through this method, we can easily modify or re- To write the behavior or properties of an object, the two-way binding mentioned before in Vue is achieved by overriding the set and get methods. So before we officially use Decorator, we use the Object.defineProperty method to achieve it. Let’s first briefly understand this method:

/**

  • obj: The object whose properties need to be modified

  • prop: The property name of the object whose properties need to be modified

  • descriptor: Description object used to define the specific behavior of the attribute
    **/
    Object.defineProperty(obj, prop, descriptor)

descriptor property Description

  • configurable: Defines whether the attribute object can be configured, that is, if it is false, the description operations (writeable, get, etc.) that define the modification are invalid

  • enumerable: Can it be traversed through for-in, or Object.keys enumerated

  • value: Define the value of the object's value attribute, value can be number, object, function, etc. Wait

  • writable: Defines whether the value value can be overwritten

  • get: A function object that will be triggered when accessing the value attribute

  • set: A function object that will be triggered when setting the value attribute

Modify a property to readonly

Understand Object After the basic syntax of .defineProperty, I first simply implement a readonly instance through it. The specific code is as follows:

Basic syntax and usage of Decorator

``javascript
# 定义
function myDecoration(target, name, descriptor) {}

# 对property使用
 class A {
 @myDecorator
 test() {}
 }

 # 对class使用
 @myDecorator
 class A {}

 # 带参数
 function myDescorator(a) {
 return function (target, name, descriptor) {
 console.llog('params:', a)
 }
 }
 @myDescorator(a) 
 class A {}

 # 时使用多个装饰器(Decorator)
 @myDecorator1
 @myDecorator2
 class A {}

Use Decorator syntax sugar to modify an attribute to readonly

Use Decorator Encapsulating PureRender for React components

We all know that there is a shouldComponentUpdate method in the React life cycle, which determines whether the component re-renders the component by returning true or false. In other words, through this method we can filter out some invalid data rendering events, thus improving performance. For example, we compare the data objects passed by props. If the attributes and values ​​of the props object have not changed, there is no need to execute the render method.

Obviously by comparing whether the properties and values ​​of the data object under props have changed, this logic can be reused, instead of repeatedly writing the shouldComponentUpdate method in each component separately. Speaking of changing the method behavior of the component object, we can obviously use the

Decorator feature to do this, that is, we override shouldComponentUpdate of the Decorator object. By traversing the properties and values ​​of the props object and comparing them with the properties and values ​​of the old props, it is determined whether re-rendering is required. The specific code is as follows:

function isEqual(a, b) {
  for (const key in a) {
    if ({}.hasOwnProperty.call(a, key) &&
      (!{}.hasOwnProperty.call(b, key) || a[key] !== b[key])) {
      return false;
    }
  }
  for (const key in b) {
    if ({}.hasOwnProperty.call(b, key) && !{}.hasOwnProperty.call(a, key)) {
      return false;
    }
  }
  return true;
}

export default function pureRender(targetComponent) {
  targetComponent.prototype.shouldComponentUpdate = function (props, state) {
    return !isEqual(this.state, state) || !isEqual(this.props, props)
  }
}

// 使用
@pureRender
class ComponentA extends React.Component {}

Using Decorator through Babel

Since Decorator is a draft in ES7, it now needs to be used through Bable. The usage method is as follows:

Install

npm install --save-dev babel-plugin-transform-decorators

Use

Method 1. Through configuration.babelrc

{
  "plugins": ["transform-decorators"]
}

Method 2, through CLI

babel --plugins transform-decorators script.js

Method 3, through Node API

require("babel-core").transform("code", {
  plugins: ["transform-decorators"]
});

Summary

Through Decorator, this does not require writing additional logic directly in the object or method In this way, you can easily extend the capabilities of objects or methods, which not only meets functional requirements, but also streamlines the code and ensures the maintainability of the code, such as our already common @log, @test, @mixin and other tool classes . Therefore, you can try more in your future work.

Reference

  • Details on ES7 JavaScript Decorators

  • ##Decorator specification

  • Exploring EcmaScript Decorators

  • Object.defineProperty

  • ##Babel Legacy Decorator plugin
  • core-decorators
  • The above content is an introduction to Decorator and related tutorials. I hope it can help everyone.

First recommendation:

Detailed explanation of function Decorator examples in JavaScript

Detailed explanation and examples of decorator

php design mode Decorator(decoration mode)

The above is the detailed content of Introduction to Decorator and related tutorials. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn