You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用JS Proxy测量类中所有函数的执行时间

类方法执行时间测量:修复Proxy问题及RxJS实现方案

修复Proxy的this指向问题

你用return () => target[prop]();导致原方法执行异常,核心原因是箭头函数丢失了正确的this指向。箭头函数没有自己的this,调用时会继承get拦截器的上下文,而不是Foo类的实例,这会导致原方法的this绑定错误,甚至无法正确执行。

正确的做法是返回一个普通包装函数,在函数内部用Reflect.apply确保原方法的this指向Proxy实例(也就是Foo的实例),同时记录执行时间:

class Foo {
    constructor() {
        return new Proxy(this, {
            get(target, prop, receiver) {
                const originalMethod = target[prop];
                // 仅拦截函数类型的属性
                if (typeof originalMethod === 'function') {
                    return function(...args) {
                        const startTime = performance.now();
                        // 用Reflect.apply保证this指向正确,同时传递所有参数
                        const result = Reflect.apply(originalMethod, this, args);
                        const endTime = performance.now();
                        console.log(`方法 '${prop}' 执行耗时:${endTime - startTime}ms`);
                        return result;
                    };
                }
                // 非函数属性直接返回原值
                return originalMethod;
            },
        });
    }

    myFn() {
        console.log('hi');
    }

    heavyTask() {
        let total = 0;
        for (let i = 0; i < 1e6; i++) total += i;
        return total;
    }
}

const foo = new Foo();
foo.myFn(); // 输出: hi + 耗时日志
foo.heavyTask(); // 输出求和结果 + 耗时日志

用RxJS实现的方案

如果你的项目已经在使用RxJS,可以把方法执行包装成Observable流,在流中完成时间测量。这种方式适合需要结合RxJS其他操作(如异步处理、重试、节流)的场景:

import { Observable } from 'rxjs';

class Foo {
    constructor() {
        return new Proxy(this, {
            get(target, prop, receiver) {
                const originalMethod = target[prop];
                if (typeof originalMethod === 'function') {
                    return function(...args) {
                        return new Observable(subscriber => {
                            const startTime = performance.now();
                            try {
                                const result = Reflect.apply(originalMethod, this, args);
                                subscriber.next(result);
                                subscriber.complete();
                                const endTime = performance.now();
                                console.log(`方法 '${prop}' 执行耗时:${endTime - startTime}ms`);
                            } catch (err) {
                                subscriber.error(err);
                            }
                        });
                    };
                }
                return originalMethod;
            },
        });
    }

    myFn() {
        console.log('hi');
        return '执行完成';
    }

    asyncTask() {
        return new Promise(resolve => setTimeout(() => resolve('异步任务完成'), 1000));
    }
}

const foo = new Foo();
// 同步方法订阅
foo.myFn().subscribe(res => console.log('结果:', res));
// 异步方法订阅
foo.asyncTask().subscribe(res => console.log('异步结果:', res));

如果只是单纯测量执行时间,纯Proxy方案更轻量;如果需要处理异步逻辑或结合RxJS生态,上述RxJS方案更合适。

内容的提问来源于stack exchange,提问作者teteyi3241

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 18:25:34