【js基础】16行js实现Currying(柯理化)

【js基础】16行js实现Currying(柯理化)
最新回答
逸迢弦语

2026-01-14 11:06:13

以下是一个16行以内的简洁实现柯里化(Currying)的JavaScript代码,结合核心逻辑与注释说明:

// 自动柯里化函数实现function curry(fn) { return function curried(...args) { // 如果传入的参数数量 >= 原始函数的形参数量,则直接执行 if (args.length >= fn.length) { return fn.apply(this, args); } // 否则返回一个新的柯里化函数,继续收集参数 else { return function(...args2) { return curried.apply(this, args.concat(args2)); }; } };}关键点解析:
  1. 闭包与递归

    外层函数curry接收目标函数fn,返回一个柯里化后的函数curried。

    curried函数通过...args收集参数,若参数不足则递归返回新函数,继续收集剩余参数。

  2. 参数数量判断

    fn.length获取原始函数的形参数量(如function(a, b)的length为2)。

    当args.length >= fn.length时,直接调用fn并传入所有参数。

  3. 参数合并

    若参数不足,返回的新函数通过args.concat(args2)合并已收集和新增的参数,继续递归调用curried。

使用示例:// 原始函数function sum(a, b, c) { return a + b + c;}// 柯里化后的函数const curriedSum = curry(sum);// 分步调用console.log(curriedSum(1)(2)(3)); // 输出: 6console.log(curriedSum(1, 2)(3)); // 输出: 6console.log(curriedSum(1)(2, 3)); // 输出: 6对比其他实现:
  • 简洁性:上述代码仅10行(不含注释),通过递归和闭包实现核心逻辑,避免冗余的partial辅助函数。
  • 灵活性:支持任意位置的参数传递(如curriedSum(1)(2, 3)),而不仅限于逐个传递。
  • 局限性:无法处理带默认参数或剩余参数的函数(如function(a, b=1, ...c)),因fn.length可能不准确。
扩展优化(16行内):

若需支持更复杂的场景(如保留this绑定),可优化为以下版本:

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

此版本使用箭头函数简化参数合并逻辑,同时保持this的正确性。