通过注入类、方法、属性参数来扩展类、属性、方法、参数;
重点:扩展;
装饰器就是一个方法
类装饰器(缺点:无法传递参数)
利用原型链
function fun1(target) {
target.prototype.userName = '张三';
// 无法传递参数,张三得写死
}
@fun1 // 等同于 fun1(Person)
class Person {
}
let p = new Person();
console.log('===>p', p.userName) // 张三
装饰器工厂
function fun(options) {
return function(target: any) {
target.prototype.userName = options.userName;
target.prototype.userAge = options.userAge;
}
}
@fun({
name: '张三',
age: 16
})
class Person {
}
const p = new Person();
console.log('===>p', p.userName)
装饰器组合
从上至下执行所有的装饰器工厂;拿到所有的装饰器之后,再从下至上执行所有的装饰器;
function demo1() {
console.log("demo1");
}
function demo2(options) {
console.log("demo2");
return function (target: any) {
console.log("demo2内部");
target.prototype.userName = options.userName;
};
}
function demo3(options) {
console.log("demo3");
return function (target) {
console.log("demo3内部");
};
}
function demo4() {
console.log("demo4");
}
@demo1
@demo2({
name: "张三",
age: 16,
})
@demo3()
@demo4
class Person {}
const p = new Person();
console.log("===>p", p.userName);
执行顺序 demo2、demo3、demo4、demo3内部、demo2内部、demo1
属性装饰器
function demo(options: any) {
return function (target: any, attr: any) {
console.log(target);
target[attr] = options;
};
}
class Person {
@demo("李四")
userName: string;
}
const p = new Person();
console.log("===>p", p.userName); // 李四