10.装饰器
2020-02-20 本文已影响0人
我只会吃饭
装饰器:
装饰器是一种特殊类型的声明,它可以被附加到类声明, 方法、属性或参数上,可以修改类的行为
简单的说 装饰器是一个方法,可以注入一些特殊的功能到类、方法、属性参数上
装饰器的写法: 普通装饰器(不可参数)、和装饰器工厂(可传参)
常见装饰器:类装饰器、属性装饰器、方法装饰器、参数装饰器
类装饰器
用于类构造函数,可以动态修改、替换、监视类的定义,在类声明之前定义(紧靠类声明)
方式一: 普通装饰器
function decorator(tar:any) {
console.log(tar);
tar.prototype.aname = 'animal';
tar.prototype.eat = function () { // 动态注入的方法
console.log('啥都吃')
}
}
@decorator
class Animal {
aname:string|undefined;
}
let animal:any = new Animal(); // 如果新增某个属性或者方法,需要将实例指定为any
console.log(animal.aname);
animal.eat();
方式二:装饰器工厂
function decoFactory(params:string) {
return function (tar:any) {
tar.prototype.aname = params;
tar.prototype.eat = function () {
console.log(`${this.aname}喜欢吃盼盼法式小面包`);
}
}
}
@decoFactory('可乐')
class Dog {}
let kele:any = new Dog();
kele.eat();
类装饰器-重载构造函数
类装饰器表达式会在运行时当作函数被调用,类的构造函数作为其唯一的参数;
类装饰器返回一个值,它会使用提供的构造函数来替换类的声明;
function overLoad(tar:any) {
return class extends tar {
aname = '火锅';
eat() {
console.log(this.aname + '喜欢吃盼盼');
}
}
}
@overLoad // 方法和属性都需要映射(必写)
class Dog {
aname:string;
constructor () {
this.aname = '可乐'
}
eat() {
console.log(this.aname + '喜欢吃狗粮');
}
}
let hg = new Dog();
hg.eat();
属性装饰器
属性装饰器会在运行时当做函数被调用,传入两个参数
1. 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
2. 属性名
function propDecorator(params:string) {
return function (target:any, prop:string) {
console.log(target, 'target'); // 原型
console.log(prop, 'props'); // 属性的名字
target[prop] = params;
}
}
class Person {
@propDecorator('我是属性装饰器')
fname:string|undefined
}
let person = new Person();
console.log(person.fname)
方法装饰器
用于方法的属性描述符上,可以监视修改替换方法的定义
方法修饰器接收三个参数: 原型对象、方法名字、方法的属性描述符
function methodDecorator(params:any) {
return function (target:any, methodName:any, desc:any) {
console.log(target);
console.log(methodName);
console.log(desc);
// 原型对象添加属性
target.fname = 'fname';
// 原型对象添加方法
target.eat = function () {
console.log('我只会吃饭');
}
// 修改装饰器的方法
let valFn = desc.value; // 为run 函数
// 重新赋值
desc.value = function (...argu:any[]) {
// 重新指向原函数,且修改参数
valFn.apply(this, argu.map(v => Number(v)));
}
}
}
class Person {
@methodDecorator('a')
// 方法装饰器,写在方法的前面
run(...argus:any[]) {
console.log(argus);
}
}
let person = new Person();
console.log(person);
person.run(1, 2, 3, '4');
方法参数装饰器
可以添加一些数据
function paramsDecorator(params:string) {
return function (target:any, methodName:string, paramsIndex: number) {
console.log(params) ; // params
console.log(target); // 原型对象
console.log(methodName); // 方法名
console.log(paramsIndex); // 参数下标
target.fname = 'fname'; // 添加数据
}
}
class Person {
say(@paramsDecorator('我是参数') name:string) {
}
}
let person = new Person();