使用Proxy包装函数时目标函数参数变为undefined的问题排查
问题:函数代理后参数变为undefined,兼容单对象/数组参数失败
场景与代码
需要让一批函数同时支持单个对象或对象数组作为入参,因此用Proxy包装函数调用,但调用后目标函数内的参数始终是undefined。
原功能函数代码
const trans = {} trans['toCssClass'] = (someListing) => { // <-- someListing 此处为 undefined console.log(someListing) someListing.a = someListing.a ? 'nonapproved' : '' someListing.d = someListing.d ? '' : 'deactivated' }
代理包装代码
function traceMethodCalls(obj) { let handler = { get(target, propKey, receiver) { const origMethod = target[propKey] return (args) => { if (Array.isArray(args)) args.forEach(arg => { console.log(arg) origMethod.apply(this, arg) }) else origMethod.apply(this, args) // <-- args 此处已定义 } } } return new Proxy(obj, handler) } export default traceMethodCalls(trans)
调用代码
const ob = {a: true, d: true} transformer['toCssClass']([ob])
问题原因
- 参数接收错误:Proxy返回的函数只声明了单个
args参数,导致调用时传入的[ob]被包裹成第二层数组(即args实际是[[ob]]),此时Array.isArray(args)判断为false,进入错误分支。 apply参数传递错误:即使进入数组遍历分支,origMethod.apply(this, arg)把单个对象arg传给了apply的第二个参数——而apply要求该参数是参数数组,它会把对象当作类数组读取,由于对象没有数字索引,原函数的参数自然为undefined。
解决方案
修正代理代码的参数接收与传递逻辑:
function traceMethodCalls(obj) { let handler = { get(target, propKey, receiver) { const origMethod = target[propKey]; return (...args) => { // 取出调用时传入的第一个参数 const input = args[0]; if (Array.isArray(input)) { input.forEach(item => { // 将单个item包装为数组传给apply,确保原函数拿到正确的单个参数 origMethod.apply(this, [item]); }); } else { // 非数组时直接传递原参数列表 origMethod.apply(this, args); } }; } }; return new Proxy(obj, handler); } export default traceMethodCalls(trans);
修正说明
- 用
...args接收所有调用参数,正确获取传入的第一个参数(可能是单对象或数组); - 遍历数组时,将每个元素包装为单个元素的数组传给
apply,确保原函数能接收到正确的单个对象参数; - 非数组场景直接传递原参数列表,兼容单对象调用。
内容的提问来源于stack exchange,提问作者BenGee23
相关产品推荐
相关产品推荐

