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

关于JavaScript通用柯里化函数中绑定函数参数长度的疑问

关于JavaScript通用柯里化实现的参数长度疑问

我在阅读一篇介绍JavaScript通用柯里化实现的文章时,遇到了如下代码:

function curry(fn) { 
  return (...xs) => { 
    if (xs.length === 0) { 
      throw Error('EMPTY INVOCATION'); 
    } 
    if (xs.length >= fn.length) { 
      return fn(...xs); 
    } 
    return curry(fn.bind(null, ...xs)); 
  }; 
}

我无法理解文中的这段解释:

我们创建一个绑定了前k个参数的fn副本,将其传给curry作为下一个fn,其参数长度(arity)减少为N-k。

想请教:在后续调用中,fn的参数长度为何会减少为N-k?绑定了k个参数的函数的参数长度难道不应该是k吗?


嘿,这个疑问太常见了,我来给你掰扯明白~

首先得搞懂一个关键:JavaScript里函数的length属性,指的是函数定义时声明的形参个数(也就是函数期待接收的参数数量,专业点叫“arity”),可不是调用时传的实参数量,也不是已经绑定的参数数量。

然后看代码里的fn.bind(null, ...xs):这是JavaScript bind方法的特殊特性——当你用bind给原函数绑定了k个前置参数后,返回的新函数的length值,会自动变成原函数的形参个数减去已经绑定的参数个数(也就是N - k)。

举个直观的例子:
假设原函数是:

function add(a, b, c) { return a + b + c; }

它的add.length是3,因为定义时声明了3个形参。

如果我们用bind绑定第一个参数:

const addWithFirst = add.bind(null, 1);

此时addWithFirst.length的值是2——因为这个新函数现在只需要接收剩下的2个参数(b和c)就能完整调用了,它的形参个数变成了3-1=2。

回到柯里化的代码逻辑:
当你第一次调用curry返回的函数时,传入了k个参数(且k < 原fn的length),代码会用bind把这k个参数绑定到原fn上,生成一个新函数。这个新函数的length就是原fn的length减去k(也就是N-k),然后把这个新函数传给下一次的curry调用。

这样下一次调用柯里化后的函数时,判断xs.length >= fn.length里的fn.length,就是这个新函数需要的剩余参数个数,直到传入的参数总数凑够原函数的形参数量,就会执行原函数返回结果。

所以你之前的误解点在于:绑定了k个参数的函数,它的length不是已经绑定的k个,而是还需要接收的剩余参数个数,也就是N-k。这正是bind方法的设计逻辑,也是这段柯里化代码能正常工作的关键~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:35:37