面试题答案
一键面试TypeScript装饰器类型
- 类装饰器:作用于类的定义,可用于修改类的定义,比如添加新的属性、方法,或者修改类的原型。示例:
function classDecorator(target: Function) {
target.prototype.newMethod = function() {
console.log('This is a new method added by the class decorator');
};
}
@classDecorator
class MyClass {}
const myObj = new MyClass();
(myObj as any).newMethod();
- 方法装饰器:作用于类的方法,可用于修改方法的属性描述符,比如改变方法的可枚举性、可写性等,或者在方法调用前后添加额外逻辑。示例:
function methodDecorator(target: Object, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function() {
console.log('Before method execution');
const result = originalMethod.apply(this, arguments);
console.log('After method execution');
return result;
};
return descriptor;
}
class AnotherClass {
@methodDecorator
myMethod() {
console.log('Inside myMethod');
}
}
const anotherObj = new AnotherClass();
anotherObj.myMethod();
- 属性装饰器:作用于类的属性,可用于在类的属性定义时添加元数据等操作。示例:
function propertyDecorator(target: Object, propertyKey: string) {
// 这里可以添加元数据等操作,例如:
Reflect.defineMetadata('key', 'value', target, propertyKey);
}
class PropertyClass {
@propertyDecorator
myProperty: string;
}
const propertyObj = new PropertyClass();
const metadata = Reflect.getMetadata('key', propertyObj,'myProperty');
console.log(metadata);
- 参数装饰器:作用于类方法的参数,可用于收集方法参数的元数据等。示例:
function parameterDecorator(target: Object, propertyKey: string, parameterIndex: number) {
// 这里可以收集参数元数据等操作,例如:
const existingMetadata = Reflect.getMetadata('parameters', target, propertyKey) || [];
existingMetadata.push(parameterIndex);
Reflect.defineMetadata('parameters', existingMetadata, target, propertyKey);
}
class ParameterClass {
myFunction(@parameterDecorator param: string) {
// 方法体
}
}
const parameterObj = new ParameterClass();
const paramMetadata = Reflect.getMetadata('parameters', parameterObj,'myFunction');
console.log(paramMetadata);
在AOP中装饰器实现功能增强的方式
- 前置增强:在方法装饰器中,通过保存原始方法,然后在新的函数中添加前置逻辑,再调用原始方法。如上述方法装饰器示例,在
originalMethod.apply(this, arguments)
之前添加的console.log('Before method execution')
就是前置增强。 - 后置增强:同样在方法装饰器中,在调用原始方法之后添加逻辑,如
console.log('After method execution')
就是后置增强。 - 环绕增强:实际上上述方法装饰器示例就是环绕增强的一种形式,它既包含前置逻辑又包含后置逻辑,将原始方法调用包裹在中间。
- 异常处理增强:在方法装饰器中,可在调用原始方法的
try - catch
块中处理异常,实现异常处理的增强。示例:
function exceptionHandlerDecorator(target: Object, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function() {
try {
return originalMethod.apply(this, arguments);
} catch (error) {
console.log('Exception caught:', error);
}
};
return descriptor;
}
class ExceptionClass {
@exceptionHandlerDecorator
riskyMethod() {
throw new Error('Simulated error');
}
}
const exceptionObj = new ExceptionClass();
exceptionObj.riskyMethod();
通过这些方式,装饰器能够在不修改原有方法或类核心逻辑的情况下,为其添加额外功能,实现AOP的功能增强。