面试题答案
一键面试装饰器执行顺序及规则分析
- 装饰器执行顺序:
- 在 TypeScript 中,装饰器的执行顺序是从最内层到最外层。对于方法装饰器,先执行方法自身的装饰器,再执行继承自基类的装饰器。在本题中,先执行
@subDecorator
,再执行@baseDecorator
。
- 在 TypeScript 中,装饰器的执行顺序是从最内层到最外层。对于方法装饰器,先执行方法自身的装饰器,再执行继承自基类的装饰器。在本题中,先执行
- 类装饰器和方法装饰器在继承结构中的规则:
- 类装饰器:类装饰器应用于类的定义。如果子类继承自应用了类装饰器的基类,子类不会自动继承基类的类装饰器。每个类的类装饰器独立作用于自身。
- 方法装饰器:当子类重写基类方法并应用自己的方法装饰器时,会先执行子类方法上的装饰器,然后执行基类方法上的装饰器(如果有的话)。
TypeScript 代码示例
// 定义基类装饰器
function baseDecorator(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log('Base decorator before method execution');
const result = originalMethod.apply(this, args);
console.log('Base decorator after method execution');
return result;
};
return descriptor;
}
// 定义子类装饰器
function subDecorator(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log('Sub decorator before method execution');
const result = originalMethod.apply(this, args);
console.log('Sub decorator after method execution');
return result;
};
return descriptor;
}
// 定义基类
class BaseClass {
@baseDecorator
baseMethod() {
console.log('Base method execution');
}
}
// 定义子类
class SubClass extends BaseClass {
@subDecorator
baseMethod() {
console.log('Sub method execution');
}
}
// 创建子类实例并调用方法
const subInstance = new SubClass();
subInstance.baseMethod();
执行过程阐述
- 创建
SubClass
实例并调用baseMethod
:- 首先遇到
@subDecorator
,执行subDecorator
函数内部逻辑。打印Sub decorator before method execution
。 - 接着执行
baseMethod
中的console.log('Sub method execution');
。 - 然后
subDecorator
函数继续执行,打印Sub decorator after method execution
。 - 之后遇到
@baseDecorator
,执行baseDecorator
函数内部逻辑。打印Base decorator before method execution
。 - 由于
SubClass
重写了baseMethod
,baseDecorator
中的originalMethod
指向SubClass
的baseMethod
经过subDecorator
装饰后的函数。 - 最后
baseDecorator
函数继续执行,打印Base decorator after method execution
。
- 首先遇到
整个执行结果输出为:
Sub decorator before method execution
Sub method execution
Sub decorator after method execution
Base decorator before method execution
Base decorator after method execution