JavaScript中的装饰器
JavaScript中的装饰器是这样的。
@classDecorator
class Person {
@methodDecorator
walk () {}
}
Decorators make it possible to annotate and modify classes and properties at design time.
A decorator is:
- an expression
- that evaluates to a function
- that takes the target, name, and decorator descriptor as arguments
- and optionally returns a decorator descriptor to install on the target object
代码中@ + 函数名是JavaScript中的装饰器。装饰器(Decorator)是一种与类(class)相关的语法,用来注释或修改类和类方法。它可以放在类和类方法的定义前面。
JavaScript中的类
JavaScript中的class是这样的。
class Person {
walk () {
consolg.log('person can walk.')
}
}
JavaScript中的class实际上是一个语法糖。
function Person () {}
Object.defineProperty(Person.protorype, 'walk', {
value: function() { consolg.log('person can walk.') },
enumerable: false,
configurable: true,
writable: true
})
作用于类的装饰器
在React中使用Redux时类装饰器十分常见。
import React, { Component } from 'react';
import { connect } from 'react-redux';
@connect(mapStateToProps, mapDispatchToProps)
export default Button extends Component {}
类装饰器就是对整个类进行修饰的。
// 这是ts中对类修饰符的声明
declare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;
@desc
class Person {}
function desc (target) {
// 为target上添加一个静态属性
target.displayName = target.name;
// 为target添加一个say共享方法
Object.defineProperty(target.protorype, 'say', {
value: function() { consolg.log('person can say.') },
enumerable: false,
configurable: true,
writable: true
})
return target;
}
对于类装饰器我们可以简单的理解为通过warp对类进行处理,只是该处理是发现在编译阶段而不是在运行时。
class Person {}
function warp (target) {
// 为target上添加一个静态属性
target.displayName = target.name;
// 为target添加一个say共享方法
Object.defineProperty(target.protorype, 'say', {
value: function() { consolg.log('person can say.') },
enumerable: false,
configurable: true,
writable: true
})
return target;
}
warp(Person);
作用于类方法的装饰器
在TypeScript中对类方法修饰器是这么声明的。
declare type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;
在JavaScript中是这么对类方法修饰器进行使用的。
function readOnly (target, propertyKey, descriptor) {
Object.defineProperty(target, propertyKey, {
...descriptor,
writable: false
})
}
class Person {
@readOnly
read () {
console.log('Person can read.');
}
}
类方法装饰器可以接受三个参数,第二个参数是装饰对象原型(不同于类的装饰,target参数指的是类本身);第二个参数是所要装饰的属性名,第三个参数是该属性的描述对象。