如何在Proxy处理器中修改Reflect函数的返回值包装结构?
问题:如何通过Proxy修改对象方法的返回值结构
我有如下代码,能正常实现调用追踪:
function traceMethodCalls(obj) { console.log('wrapping brain API') const handler = { get(target, propKey, receiver) { console.log('GET', propKey); return Reflect.get(target, propKey, receiver); } }; return new Proxy(obj, handler) }
但我希望进一步修改函数的返回值结构,于是尝试将handler修改为如下形式:
function traceMethodCalls(obj) { console.log('wrapping brain API') const handler = { get(target, propKey, receiver) { console.log('GET', propKey); const wrap = () => { const result = Reflect.get(target, propKey, receiver) return { result: result, api: 'api' } } return wrap } }; return new Proxy(obj, handler) }
修改后得到的结果是Reflect对应的匿名函数,若在handler中直接调用该函数又会出现错误,请问该如何正确实现修改返回值结构的需求?
解决方案
你的问题出在两个核心点:一是不管属性是否为函数都返回包装函数,导致非函数属性行为异常;二是包装函数仅获取了原方法的引用,没有执行它,也未处理调用时的参数和this绑定。正确实现需要针对函数属性做定向包装,保留参数与this上下文,再修改返回值结构:
function traceMethodCalls(obj) { console.log('wrapping brain API') const handler = { get(target, propKey, receiver) { console.log('GET', propKey); const originalValue = Reflect.get(target, propKey, receiver); // 仅对函数类型的属性进行包装 if (typeof originalValue === 'function') { return function(...args) { // 处理this绑定:如果当前this是Proxy实例,绑定到原对象target,否则保持当前this const context = this === receiver ? target : this; // 调用原方法并传递所有参数 const result = originalValue.apply(context, args); // 返回自定义结构,用propKey标识对应API更灵活 return { result: result, api: propKey }; }; } // 非函数属性直接返回原内容 return originalValue; } }; return new Proxy(obj, handler) }
关键细节说明:
- 区分函数与非函数属性:只对函数类型的属性做包装,避免破坏原对象的非函数属性行为
- 完整保留参数传递:使用
...args接收调用时的所有参数,保证原方法能正常获取输入 - 正确绑定执行上下文:通过
apply指定this指向,避免因this指向Proxy实例导致的逻辑异常 - 自定义返回结构:在原方法执行完成后,将结果封装到你需要的对象结构中返回
内容的提问来源于stack exchange,提问作者Curcuma_
相关产品推荐
相关产品推荐

