函数的length属性表示从左到右第一个带默认值形参前的普通形参个数,仅由语法结构决定,不参与运行时逻辑;如f(a,b=1)中length为1,g(a=1,b)中length为0。

函数的 length 属性不是“最少要传几个参数”,而是**从左到右数,第一个带默认值的形参之前有多少个普通形参**。它只看函数定义的语法结构,不参与运行时逻辑,也不影响调用行为。
length 只统计“默认值左侧”的普通参数
JavaScript 解析函数声明时,从左开始扫描形参列表,一旦遇到带默认值的参数(包括 =、解构默认值、或剩余参数前的参数),就立即停止计数,前面的非默认参数个数就是 length 值。
-
function f(a, b = 1) {}→f.length === 1(a在默认参数b左侧) -
function g(a = 1, b) {}→g.length === 0(a自身带默认值,左侧无非默认参数) -
function h([x] = [0]) {}→h.length === 1(整个解构参数算一个形参,且带默认值,故左侧无非默认参数) -
function i(a, ...rest) {}→i.length === 1(...rest不计入length,但不影响前面已统计的a)
默认值位置直接影响 length,但不改变调用自由度
length 数值可能和你直觉中的“必填参数”不一致,尤其当默认值出现在开头或中间时:
-
function j(x = 1, y) {}→j.length === 0,但你无法只传y:调用j(2)会把2赋给x,y仍是undefined -
function k(a, b, c = 3, d = 4) {}→k.length === 2,但你可以只传a,或全都不传(a和b都会是undefined) - 没有运行时机制根据
length检查、报错或自动补值——它只是静态属性
bind 和箭头函数也遵守同一规则
绑定函数和箭头函数的 length 并非特例,而是延续了相同的语法解析逻辑:
-
const add = (a, b) => a + b;→add.length === 2 -
const add5 = add.bind(null, 5);→add5.length === 1(原length减去前置已绑定参数个数) -
const partial = add.bind(null, 5, 6);→partial.length === 0 -
const empty = () => {};→empty.length === 0
别把它当契约,它是工具属性
length 常被用于函数式编程库中做参数推断(如柯里化、装饰器)、或配合 TypeScript/JSDoc 做类型提示,但它本身不构成任何运行时约束:
- 你可以少传、多传、跳过任意参数,JS 引擎不会因
length报错 - 它不能反映实际可安全省略的参数——例如
function m(a, b = 1, c) {}的length === 1,但c实际上无法在不传b的情况下被单独赋值 - 真正决定行为的是默认值赋值规则、参数顺序、以及
arguments或剩余参数展开逻辑











