事前准备
- npm init -y
- tsc --init
- npm install ts-node --save-dev
- npm install typescript --save
- package.json 配置
"dev": "ts-node ./src/index.ts"
类的装饰器(一)
- 我们有一个calss类,对类做修饰
- 什么时候执行,他会在class类创建好之后,立即就去执行这个装饰器@,不是每次实例化的时候才执行
const test = new Test();
(test as any).getName();
装饰器本身是一个函数
类装饰器接受的参数是构造函数
装饰器通过 @ 符号来使用
装饰器是实验性语法,需要打开tsconfig.json里的配置项
"experimentalDecorators": true
"emitDecoratorMetadata": true
// 方法一
function testDecorator(constructor: any) {
constructor.prototype.getName = () => {
console.log()
}
}
// 方法二
function testDecorator(flag: boolean) {
if(flag) {
return function (constructor: any) {
constructor.prototype.getName = () => {
console.log()
}
}
}else{
return function (constructor: any) {}
}
}
@testDecorator(true)
class Test{}
const test = new Test();
(test as any).getName()
类的装饰器(二)
function testDecorator() {
return function <T extends new (...arg: any[]) => any> (constructor: T) {
return class extends constructor {
name = 'duke',
getName() { return this.name }
}
}
}
const Test = testDecorator()(
class {
name: string,
constructor(name: string) { this.name = name }
}
)
const test = new Test('jack');
// (test as any).getName();
test.getName();
方法装饰器
// 普通方法,target对应的是类的prototype
// 静态方法,target对应的是类的构造函数
function getNameDecorator(target:any, key:string, descriptor: PropertyDescriptor ) {
// getName不能被重写
descriptor.writable = false;
// 对方法的变更
descriptor.value = function() {
return "over"
}
}
class Test {
name: string,
constructor(name: string) { this.name = name }
@getNameDecorator
getName() { return this.name }
}
const test = new Test('jack');
访问器的装饰器
- get 和 set 不能同时加 decorator,不然会报错
function visitDecorator(target:any, key:string, descriptor: PropertyDescriptor ) {
// name不能被修改
descriptor.writable = false;
}
class Test {
private _name: string,
constructor(name: string) { this._name = name }
get name() { return this._name }
@visitDecorator
set name(name: string) { this._name = name }
}
const test = new Test('jack');
test.name = "over"
属性的装饰器
- 只能接受2个参数 target and key
function nameDecorator(target:any, key:string): any {
const descriptor: PropertyDescriptor = {
writable: false
}
// 修改的并不是实例上的 name, 而是原型上的 name
targrt[key] = 'dragon'
return descriptor
}
// name是放在实例上的,并不是在原型上
class Test {
@nameDecorator
name = string,
}
const test = new Test('jack');
参数装饰器
// 原型,方法名,参数所在的位置
function paramDecorator (target:any, method:string, paramIndex:number) { }
class Test {
getInfo(@paramDecorator name:string, age:number) {}
}
const test = new Test();
test.getInfo('jack', 30)
装饰器实际使用的小例子
const userInfo: any = undefined;
function catchError(target:any, key:string, descriptor: PropertyDescriptor ) {
const fn = descriptor.value;
descriptor.value = function() {
try{
fn()
}catch(e){
console.log("有错误")
}
}
}
class Test {
@catchError
getName() {
return userInfo.name
}
}
结语
前端react QQ群:
788023830----React/Redux - 地下老英雄前端交流 QQ群:
249620372----FRONT-END-JS前端(我们的宗旨是,为了加班,为了秃顶……,仰望大佬),希望小伙伴们加群一起学习