简单介绍:
装饰器本质是一种特殊的函数,它可以对:类、属性、方法、参数进行扩展;同时能让代码更简洁。
装饰器分类(5种):
- 类装饰器
- 属性装饰器
- 方法装饰器
- 访问器装饰器
- 参数装饰器
接上文 TypeScript完整学习 ,【自动化编译中查看】,终端输入 tsc --init
后,我们需要在tsconfig.json文件中打开"experimentalDecorators": true,
设置;终端输入tsc --watch
来监视目录中所有的.ts 文件变化。
类装饰器:
类装饰器是一个应用在类声明上的函数,可以为类添加额外的功能,或添加额外的逻辑。
基本语法:
// 装饰器 Demo函数会在Person类定义时执行,参数说明:target参数是被装饰的类,即Person
function Demo(target: Function) {console.log(target);/**打印结果:* class Person { * constructor(name, age) * { this.name = name; * this.age = age;}}* */
}@Demo
class Person {constructor(public name: string, public age: number) { }
}
应用举例:
需求:定义一个装饰器,实现Person实例调用 toString
时返回 JSON.stringify
的执行结果
// 装饰器
function CustomString(target: Function) {target.prototype.toString = function(){// 这里要返回的是target的实例对象,所以是thisreturn JSON.stringify(this)}// seal 对指定对象进行封锁,不允许在traget的原型链上做文章Object.seal(target.prototype)
}@CustomString
class Person {constructor(public name: string, public age: number) { }
}const p1 = new Person('张三', 19)
console.log(p1.toString()); //打印结果为:{"name":"张三","age":19}
关于返回值:
类装饰器有返回值:若类装饰器返回一个新的类,那这个新类将替换掉被装饰的类。
类装饰器无返回值:若类装饰器无返回值或返回值为 undefined ,那被装饰的类不会被替换。
// 装饰器
function Demo(target: Function) {return class {test() {console.log(200);console.log(300);console.log(400);}}
}@Demo
class Person {test() {console.log(100);}
}console.log(Person);
/**打印结果:
class {test() {console.log(200);console.log(300);console.log(400);}
}
*/
关于构造类型:
在TypeScript中,Function
类型所表示的范围十分广泛,包括:普通函数、箭头函数、方法等等…但Function类型的函数不是都可以被new
关键字实例化,例如:箭头函数是不能被实例化的。那么在TypeScript 中如何声明一个构造类型呢?有以下两种方法:
第一种 ➡ 仅声明构造类型:
完整代码:
// 定义Constructor类型,其含义是构造类型
type Constructor = new (...args: any[]) => {}// 需求:fn是一个类
function test(fn: Constructor) { }class Person { }test(Person)
type Constructor = new (...args: any[]) => {}
介绍 | |
---|---|
new | 该类型是可以用new操作符调用 |
...args | 构造器可以接收【任意数量】的参数 |
any[] | 构造器可以接收【任意类型】的参数 |
{} | 返回的类型是对象(非null、非undefined的对象) |
第二种 ➡ 声明构造类型 + 指定静态属性:
// 定义一个构造函数,且包含一个静态属性wife
type Constructor = {new (...args: any[]):{}wife:string //静态属性
}// 需求:fn是一个类
function test(fn: Constructor) { }class Person { // static 关键字:声明静态成员变量、方法和代码块static wife:string
}test(Person)
替换被装饰的类:return
对于高级的一些装饰器,不仅仅是覆盖一个原型上的方法,还要有更多功能,例如添加新的方法和状态。
举例: 需求是设计一个LogTime 装饰器,可以给实例添加一个属性,用于记录实例对象的创建时间,再创建一个方法用于读取创建时间。
type Constructor = new (...args: any[]) => {}interface Person {getTime(): void
}// 泛型约束 <T extends Constructor>
function LogTime<T extends Constructor>(target: T) {return class extends target {createdTime: Dateconstructor(...args: any[]) {super(...args)this.createdTime = new