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

为何JavaScript中Function.length属性会排除剩余参数?

理解JavaScript中的函数元数(arity)与剩余参数的length陷阱

最近在探索RambdaJS的柯里化函数时,我发现了一个很有意思的用法,举个直观的例子:

var addFourNumbers = (a, b, c, d) => a + b + c + d;
var curriedAddFourNumbers = R.curry(addFourNumbers);
var f = curriedAddFourNumbers(1, 2);
var g = f(3);
g(4); //=> 10

很多函数式编程语言原生就支持柯里化,但在JS里这操作看起来有点像"魔法"。而要搞懂柯里化的底层逻辑,首先得知道怎么判断一个函数的元数(arity)——也就是它预期接收的参数数量。

其实答案特别简单,直接用函数的length属性就行,相关定义是这样的:

length属性表示函数预期接收的参数数量。

看个基础示例就懂了:

function func1() {}
function func2(a, b) {}
console.log(func1.length); // expected output: 0
console.log(func2.length); // expected output: 2

不过这里有个容易踩坑的点:剩余参数会被length属性排除在外,比如这个例子:

function a(...d) { console.log(d) }
console.log(a.length); // expected output: 0

乍一看有点奇怪——函数a明明定义了接收一个参数d(虽然是数组形式),为什么length会是0?这到底是合理设计还是JS又一个让人吐槽的"WAT"特性?

其实这是有意为之的设计,不是bug。原因在于:剩余参数的本质是收集所有未被显式声明的参数,它并不代表函数预期接收的固定参数数量。length属性的核心语义是反映函数定义中显式声明的、非剩余参数的个数——简单说就是,调用这个函数时"至少"需要传入多少个参数。

比如如果我们写:

function b(x, ...y) {}
console.log(b.length); // expected output: 1

这里length是1,因为x是必须显式传入的第一个参数,而...y是用来兜底处理额外参数的,不属于"预期必须传入"的范畴。

当函数只有剩余参数时,length为0其实也符合这个逻辑:这个函数没有要求调用者必须传入任何参数,所有传入的参数都会被收集到剩余参数里。虽然直观上可能有点反常识,但这是JS为了保持length属性语义一致性做出的选择,算不上"WAT"特性,而是有明确设计意图的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:33:38