函数的 length 属性

Function.prototype.length 返回函数定义时的形参数量,不包括默认参数和剩余参数,常用于柯里化和函数式编程。

#resource / javascript #resource / ecmascript #type / concept #status / evergreen

[!info] related notes

函数的 length 属性

一句话定义

Function.prototype.length 返回函数定义时的形参数量(参数个数),不包括有默认值的参数和剩余参数。

核心机制

基本行为

function fn(a, b, c) {}
console.log(fn.length); // 3

function fn2(a, b, c = 1) {}
console.log(fn2.length); // 2

function fn3(...args) {}
console.log(fn3.length); // 0

关键规则

  1. 只计算形参:不计算实际传入的参数数量
  2. 不包括默认参数:有默认值的参数不计入
  3. 不包括剩余参数...rest 参数不计入
  4. 从第一个有默认值的参数开始停止计数

详细示例

// 1. 普通函数
function add(a, b) { return a + b; }
console.log(add.length); // 2

// 2. 有默认值的参数
function greet(name, greeting = 'Hello') {
  return `${greeting}, ${name}`;
}
console.log(greet.length); // 1

// 3. 剩余参数
function sum(...numbers) {
  return numbers.reduce((a, b) => a + b, 0);
}
console.log(sum.length); // 0

// 4. 混合情况
function mixed(a, b = 1, c, d = 2) {
  return a + b + c + d;
}
console.log(mixed.length); // 1(从第一个默认参数 b 开始停止计数)

// 5. 箭头函数
const arrowFn = (a, b, c) => a + b + c;
console.log(arrowFn.length); // 3

// 6. bind() 返回的函数
const boundFn = add.bind(null, 1);
console.log(boundFn.length); // 1(剩余参数数量)

实际应用

1. 柯里化实现

在实现柯里化函数时,length 属性用于判断何时参数已经足够:

function curry(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn.call(this, ...args);
    }
    return curried.bind(this, ...args);
  };
}

const add = (a, b, c) => a + b + c;
console.log(add.length); // 3

const curriedAdd = curry(add);
curriedAdd(1)(2)(3); // 6

2. 参数验证

可以用于验证函数调用时是否传入了足够数量的参数:

function validateArgs(fn, ...args) {
  if (args.length < fn.length) {
    throw new Error(`需要 ${fn.length} 个参数,但只传入了 ${args.length} 个`);
  }
  return fn(...args);
}

3. 函数签名分析

可以用于分析函数的参数数量:

function analyzeFunction(fn) {
  return {
    name: fn.name,
    parameterCount: fn.length,
    isVariadic: fn.length === 0 && fn.toString().includes('...')
  };
}

常见误解

1. 与 arguments.length 的区别

function fn(a, b) {
  console.log(fn.length);        // 2(定义时的形参数量)
  console.log(arguments.length); // 3(调用时的实参数量)
}

fn(1, 2, 3);

2. 箭头函数没有 arguments

const arrowFn = (a, b) => {
  // console.log(arguments); // ReferenceError: arguments is not defined
  console.log(arrowFn.length); // 2
};

3. 默认参数的影响

// ❌ 错误理解:认为是 3
function fn(a, b = 1, c) {}
console.log(fn.length); // 1

// ✅ 正确理解:从第一个默认参数开始停止计数
// fn.length 只计算 a,不计算 b 和 c

BFE.dev 相关题目

  • 1. implement curry():使用 fn.length 判断参数数量
  • 19. this:理解函数调用时的参数传递

面试要点

  1. 基本概念:知道 length 返回定义时的形参数量
  2. 默认参数:理解默认参数不计入 length
  3. 剩余参数:理解剩余参数不计入 length
  4. 柯里化应用:知道如何在柯里化中使用 length
  5. 与 arguments.length 的区别:能区分两者

信息参考

创建于 2026/3/31 更新于 2026/5/27