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

如何改造JS柯里化add函数使其执行后直接返回数字类型而非函数对象

问题说明

你当前实现的add函数支持柯里化链式调用,在隐式转换场景下会展示为求和结果,但实际返回值类型为函数,需要实现返回严格数字类型,满足console.log(typeof ext.add(1)) // number的效果。

核心矛盾说明

传统的同步链式柯里化求和方案,依赖返回函数实现连续调用,重写toString/valueOf仅能实现隐式转换为数字,无法改变变量本身的函数类型,要实现严格数字类型返回,需要对调用逻辑做调整,以下是三种可选实现方案:


方案1:放弃链式调用,直接返回数字

如果不需要支持ext.add(3, 1)()(3)这类连续调用,直接修改add逻辑,调用即返回求和结果:

function Ext() {
  let cs = 0;
  return {
    add: function add(...num) {
      const sum = num.reduce((a, b) => a + b, 0);
      cs += sum;
      return sum;
    }
  }
}

const ext = Ext();
console.log(typeof ext.add(1)) // number
console.log(ext.add(1) === 1) // true
console.log(ext.add(3,1)) // 4

注意:该方案无法支持链式调用,ext.add(1)(2)会抛出类型错误


方案2:保留链式调用,无参数时自动返回数字

调整逻辑,链式调用阶段返回可执行函数,传入空参数调用时直接返回数字类型的结果:

function Ext() {
  let cs = 0;

  function pars(fn) {
    let newFn = fn.bind(null);

    function cal(...num) {
      // 无参数传入时直接返回计算结果
      if(num.length === 0) {
        const res = newFn();
        newFn = fn.bind(null);
        return res;
      }
      newFn = newFn.bind(null, ...num);
      return cal;
    }
    // 保留隐式转换能力兼容旧逻辑
    cal.toString = () => newFn();
    cal.valueOf = () => newFn();

    return (...num) => {
      newFn = fn.bind(null);
      return cal(...num);
    };
  }

  const _add = pars((...num) => {
    num.forEach((item) => { cs += item; });
    return num.reduce((a, b) => a + b, 0);
  });

  return {
    add: function add(...num) {
      return _add(...num);
    }
  }
}

const ext = Ext();
console.log(ext.add(1)()) // 1
console.log(typeof ext.add(1)()) // number
console.log(ext.add(3,1)()(3)()) // 7
console.log(typeof ext.add(3,1)()(3)()) // number

方案3:异步Promise实现(匹配你注释中的思路)

将返回值改为Promise,异步返回数字类型的结果:

function Ext() {
  let cs = 0;

  function pars(fn) {
    let newFn = fn.bind(null);

    function cal(...num) {
      newFn = newFn.bind(null, ...num);
      return cal;
    }

    cal.toString = () => newFn();
    cal.valueOf = () => newFn();

    return (...num) => {
      newFn = fn.bind(null);
      return cal(...num);
    };
  }

  const _add = pars((...num) => {
    num.forEach((item) => { cs += item; });
    return num.reduce((a, b) => a + b, 0);
  });

  return {
    add: function add(...num) {
      return new Promise(resolve => {
        const result = _add(...num);
        resolve(Number(result));
      })
    }
  }
}

const ext = Ext();
ext.add(1).then(res => {
  console.log(typeof res) // number
  console.log(res === 1) // true
})

注意:该方案返回值为Promise类型,无法直接同步拿到数字结果


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 14:18:04