MST

星途 面试题库

面试题:TypeScript类装饰器的高级应用

编写一个TypeScript类装饰器,用于记录类中所有方法的调用次数。装饰器需要能够在运行时统计每个方法被调用的次数,并提供一个方法可以查看所有方法的调用次数。请给出详细的代码实现,并说明装饰器在类定义和使用过程中的工作原理。
22.0万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试
// 类装饰器工厂函数
function methodCallCounter() {
    return function (target: Function) {
        const methodCalls: { [key: string]: number } = {};
        const originalPrototype = target.prototype;
        // 遍历类的原型上的所有方法
        for (const methodName in originalPrototype) {
            if (typeof originalPrototype[methodName] === 'function') {
                const originalMethod = originalPrototype[methodName];
                // 重写方法,每次调用增加计数器
                originalPrototype[methodName] = function (...args: any[]) {
                    if (!methodCalls[methodName]) {
                        methodCalls[methodName] = 1;
                    } else {
                        methodCalls[methodName]++;
                    }
                    return originalMethod.apply(this, args);
                };
            }
        }
        // 添加一个方法用于查看所有方法的调用次数
        target.prototype.getMethodCallCounts = function () {
            return methodCalls;
        };
    };
}

// 使用装饰器
@methodCallCounter()
class MyClass {
    method1() {
        console.log('Method 1 called');
    }
    method2() {
        console.log('Method 2 called');
    }
}

const myClassInstance = new MyClass();
myClassInstance.method1();
myClassInstance.method1();
myClassInstance.method2();

console.log(myClassInstance.getMethodCallCounts());

装饰器工作原理说明

  1. 定义装饰器工厂函数 methodCallCounter:返回一个实际的装饰器函数。
  2. 实际装饰器函数:接收类的构造函数 target 作为参数。
  3. 初始化调用次数记录对象 methodCalls:用于存储每个方法的调用次数。
  4. 遍历类原型上的方法:对于每个方法,重写该方法,在方法调用前增加对应方法在 methodCalls 中的计数。
  5. 添加 getMethodCallCounts 方法:到类的原型上,用于获取所有方法的调用次数。
  6. 使用装饰器:在类定义前使用 @methodCallCounter(),这样在类定义时,装饰器函数就会对类进行处理,重写方法并添加获取调用次数的方法。在类实例化后调用方法,调用次数会被统计,通过调用 getMethodCallCounts 方法可以查看结果。