简单介绍:
装饰器本质是一种特殊的函数,它可以对:类、属性、方法、参数进行扩展;同时能让代码更简洁。
装饰器分类(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的实例对象,所以是this
return 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: Date
constructor(...args: any[]) {
super(...args)
this.createdTime = new Date()
}