装饰器
装饰器的写法
1.1 普通装饰器
interface Person {
name: string
age: string
}
function enhancer(target: any) {
target.prototype.name = '金色小芝麻'
target.prototype.age = '18'
}
@enhancer // 普通装饰器
class Person {
constructor() { }
}
复制代码
1.2 装饰器工厂
interface Person {
name: string
age: number
}
// 利用函数柯里化解决传参问题, 向装饰器传入一些参数,也可以叫 参数注解
function enhancer(name: string) {
return function enhancer(target: any) {
// 这个 name 就是装饰器的元数据,外界传递进来的参数
target.prototype.name = name
target.prototype.age = 18
}
}
@enhancer('小芝麻') // 在使用装饰器的时候, 为其指定元数据
class Person {
constructor() {}
}
复制代码
2、装饰器的分类
2.1 类装饰器
类装饰器在类声明之前声明(紧靠着类声明),用来
监视
、修改
或者替换
类定义
- 类装饰器不能用在声明文件中(
.d.ts
),也不能用在任何外部上下文中(比如declare
的类)。 - 类装饰器表达式会在运行时当作函数被调用,类的构造函数作为其唯一的参数。
- 如果类装饰器返回一个值,它会使用提供的构造函数来替换类的声明。
interface Person {
name: string
age: string
}
function enhancer(target: any) {
target.xx = 'Person' ; // 给类增加属性
target.prototype.name = '金色小芝麻'
target.prototype.age = '18'
}
@enhancer // 名字随便起
class Person {
constructor() { }
}
let p = new Person()
console.log(Person.name); // Person
console.log(p.age) // 18
复制代码
2.2 属性装饰器
- 属性装饰器用来装饰属性
- 属性装饰器表达式会在运行时当做函数被调用,传入下列两个参数
- 第一个参数: 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
- 第二个参数: 是属性的名称
function enhancer(target: any, propertyKey: string) {
console.log(target); // Person {}
console.log("key " + propertyKey); // key name
};
class Person {
@enhancer
name: string;
constructor() {
this.name = '金色小芝麻';
}
}
const user = new Person();
user.name = '你好啊!'
console.log(user.name) // 你好啊!
复制代码
2.3 方法装饰器
- 方法装饰器用来装饰方法
- 第一个参数: 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
- 第二个参数: 是方法的名称
- 第三个参数: 是方法的描述 修饰方法
function enhancer(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
// target 如果装饰的是个普通属性的话,那么这个 target 指向类的原型 Person.prototype
console.log(target); // Person { getName: [Function] }
console.log("key " + propertyKey); // key getName
console.log("desc " + JSON.stringify(descriptor)); // {"writable":true,"enumerable":true,"configurable":true}
};
class Person {
name: string;
constructor() {
this.name = '金色小芝麻';
}
@enhancer
getName() {
return 'getName';
}
}
const user = new Person();
user.getName = function () {
return '金色小芝麻'
}
console.log(user.getName()); // '金色小芝麻'
复制代码
修饰静态方法
// 声明装饰器修饰静态方法
function enhancer(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
// target 装饰的是一个类的属性static,那么这个 target 指向类的定义
console.log(target); // [Function: Person] { getAge: [Function] }
console.log("key " + propertyKey); // key getAge
console.log("desc " + JSON.stringify(descriptor)); // {"writable":true,"enumerable":true,"configurable":true}
};
class Person {
age: number = 18;
constructor() {}
@enhancer
static getAge() {
return 'static getAge';
}
}
const user = new Person();
Person.getAge = function () {
return '你好啊!'
}
console.log(Person.getAge()) // 你好啊!
2.4 参数装饰器
- 参数装饰器用来装饰参数
- 第一个参数: 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
- 第二个参数: 成员的名字
- 第三个参数: 参数在函数参数列表中的索引
function enhancer(target: any, propertyKey: string, parameterIndex: number) {
console.log(target); // Person { getName: [Function] }
console.log("key " + propertyKey); // key getName
console.log("index " + parameterIndex); // index 0
};
class Person {
name: string;
constructor() {
this.name = '你好啊!';
}
getName(@enhancer name: string){
return name
}
}
const user = new Person();
user.name = '金色小芝麻'
console.log(user.name) // '金色小芝麻'
2.5 装饰器执行顺序
- 属性方法先执行,谁先写 先执行谁
- 方法的时候, 先参数在方法,而且一定会在一起
- 最后是类
- 如果同类型,先执行离类近的
3、装饰器的原理
链接到当前文件 0
没有文件链接到当前文件