0%

装饰器、泛型

装饰器

方法装饰器

LogComponent组件只为负责打印日志,通过log装饰器修饰printLog方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
export class LogComponent {
@log
printLog(str) {
return str;
}
}
function log(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) {
// descriptor is a object contains writable, enumberable, configurable, setter, getter, value;
let origin = descriptor.value;
descriptor.value = function (...args) { // apply方法
console.log(this); // LogComponent
let result = origin.apply(this, args);
console.log('Log is - ' + result);
return result;
}
return descriptor;
}

应用场景: 可以在其他组件内继承LogComponent,也可以封装为一个service,服务于各个组件,职责单一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
export class AppComponent extends LogComponent  implements OnInit {
constructor(
private viewContainerRef: ViewContainerRef,
private renderer: Renderer2,
private elementRef: ElementRef,
) {
super();
}
ngOnInit(): void {
this.setupMenus();
this.printLog('test');
}
printLog(str) {
super.printLog(str);
}
}

参数装饰器

1
2
3
4
5
6
7
8
9
@Injectable()
export class AppService {
login( @Inject name: string) { }
}

function Inject(target: Object, propertyKey: string, parameterIndex: number) {
console.log(propertyKey); // login 参数名称,注意是方法名
console.log(parameterIndex); // 0 参数索引
}

泛型(Generic)

集合类型如果设置为any可以实现同时支持多种类型,但是放弃了原本支持的类型检查,泛型则是为了解决这一点;帮助进行后面的类型检查

class Name<T>{
    sayName(name:T): void{
        console.log(' hello, i'm ' + name);
    }
}
let user1 = new Name<string>();
user1.sayName('lee');

let user2 = new Name<number>();
user2.sayName(3);