javascript柯里化是什么_如何实现函数的柯里化

柯里化是将多参函数转为单参函数链的过程,通过闭包累积参数、延迟求值,核心为固定参数+返回函数链;示例curry函数基于fn.length判断参数是否齐备,支持多种调用方式。

柯里化(Currying)是将一个接收多个参数的函数,转换为一系列只接收一个参数的函数的过程。每次调用返回一个新的函数,直到收集齐所有参数,才真正执行原函数。

柯里化的核心特点

它不是简单地“分次传参”,而是通过闭包保存已传入的参数,逐步累积,最终触发计算。关键在于:固定部分参数 + 延迟求值 + 返回函数链。

手动实现一个基础柯里化函数

下面是一个通用、可复用的 curry 工具函数:

function curry(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn.apply(this, args);
    } else {
      return function(...nextArgs) {
        return curried.apply(this, args.concat(nextArgs));
      };
    }
  };
}

说明:

  • fn.length 获取原函数期望的形参个数,作为“收参完成”的判断依据
  • 每次调用 curried 时,先检查当前参数是否足够;够了就执行,不够就返回新函数继续等
  • 使用 apply 保证 this 上下文和参数数组正确传递

实际例子:加法函数柯里化

原始函数:

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

柯里化后使用方式:

const curriedAdd = curry(add);
console.log(curriedAdd(1)(2)(3)); // 6
console.log(curriedAdd(1, 2)(3)); // 6
console.log(curriedAdd(1)(2, 3)); // 6

三种写法都有效,因为内部做了参数合并逻辑。

进阶注意点

真实项目中需考虑更多边界情况:

  • 支持 显式指定参数个数(如 curry(fn, 3)),避免依赖 fn.length(箭头函数、无名函数或含默认参数时 length 不可靠)
  • 处理 arguments 对象或类数组,必要时用 Array.from 转换
  • 若需保留原函数的属性(如 name、length),可用 Object.assign 或 defineProperty 拷贝
  • 某些场景下希望支持“占位符”(如 _),类似 Lodash 的 curry,需额外解析参数中的占位标识

不复杂但容易忽略