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

如何实现可多次调用的defaultMethod?参数默认值继承问题

解决defaultMethod函数多次调用失效问题

需求说明

实现defaultMethod函数,接收一个目标函数与默认参数字典,返回带有默认参数的新函数,核心要求是支持多次调用更新默认参数:

  • 基础示例:
    function add(a,b) { return a+b;};
    var add_ = defaultMethod(add,{b:9});
    console.log(add_(10)); // 预期返回19(10+9)
    
  • 多次调用示例:
    var add_ = defaultMethod(add,{b:9}); // 初始设置b默认值9
    add_ = defaultMethod(add_,{b:3, a:2}); // 更新b为3、添加a默认值2
    let res = add_(10); // 传入a=10
    console.log(res); // 预期返回13(10+3)
    

现有实现的问题

现有代码单次调用正常,但多次调用时,console.log(requiredArgs)输出['...args']而非原函数的['a','b'],导致逻辑失效。原因是:第一次调用defaultMethod返回的是匿名包装函数,第二次传入该包装函数时,func.toString()解析的是包装函数的参数(...args),而非原始目标函数的参数列表。

解决方案

核心思路是让每个包装函数保留原始目标函数的引用,同时累计每次传入的默认参数,确保多次调用时始终能获取到正确的参数列表和最新的默认值。修改后的代码如下:

function defaultMethod(func, params) {
    // 追溯到最原始的目标函数,避免解析包装函数的参数
    const originalFunc = func.__originalFunc__ || func;
    const funcStr = originalFunc.toString();
    const requiredArgs = funcStr
      .slice(funcStr.indexOf('(') + 1, funcStr.indexOf(')'))
      .match(/([^\s,]+)/g) || [];

    // 创建新的包装函数
    const wrappedFunc = function (...args) {
      const calledArgs = [...args]; // 复制参数数组,避免修改原数组
      // 合并历史默认参数与新传入的参数,新参数覆盖旧值
      const mergedDefaults = {...func.__defaultParams__, ...params};

      // 填充缺失的参数
      for (let i = 0; i < requiredArgs.length; i++) {
        if (calledArgs[i] === undefined) {
          calledArgs[i] = mergedDefaults[requiredArgs[i]];
        }
      }

      return originalFunc(...calledArgs);
    };

    // 给包装函数添加属性,存储原始函数和累计的默认参数
    wrappedFunc.__originalFunc__ = originalFunc;
    wrappedFunc.__defaultParams__ = {...func.__defaultParams__, ...params};

    return wrappedFunc;
  }

关键修改点

  1. 保留原始函数引用:通过自定义属性__originalFunc__,每次调用都能获取到最开始的目标函数,确保参数解析始终正确
  2. 累计默认参数:用__defaultParams__存储每次传入的默认参数,新参数会覆盖旧的同名参数,实现默认值的更新
  3. 参数数组隔离:复制args数组避免修改原输入,保证函数的纯净性

测试验证

运行多次调用的示例代码,输出结果为13,符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 14:22:42