当前位置:首页 > JavaScript

函数柯里化 js实现

2026-04-04 21:41:54JavaScript

函数柯里化的概念

函数柯里化(Currying)是一种将多参数函数转换为一系列单参数函数的技术。通过柯里化,可以将一个接收多个参数的函数分解为多个接收单个参数的函数链式调用。

基础柯里化实现

以下是一个简单的柯里化函数实现,支持固定参数数量的函数:

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));
      };
    }
  };
}

使用示例:

函数柯里化 js实现

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

支持占位符的柯里化

通过引入占位符(如 _),可以更灵活地延迟某些参数的传递:

function curryWithPlaceholder(fn) {
  return function curried(...args) {
    const complete = args.length >= fn.length && !args.includes(curryWithPlaceholder.placeholder);
    if (complete) {
      return fn.apply(this, args);
    } else {
      return function (...nextArgs) {
        const mergedArgs = args.map(arg => 
          arg === curryWithPlaceholder.placeholder && nextArgs.length ? nextArgs.shift() : arg
        ).concat(nextArgs);
        return curried.apply(this, mergedArgs);
      };
    }
  };
}

curryWithPlaceholder.placeholder = '_';

使用示例:

函数柯里化 js实现

function multiply(a, b, c) {
  return a * b * c;
}

const curriedMultiply = curryWithPlaceholder(multiply);
console.log(curriedMultiply('_', 2)(1)(3)); // 输出 6 (1 * 2 * 3)
console.log(curriedMultiply(1, '_', 3)(2)); // 输出 6 (1 * 2 * 3)

无限参数柯里化

对于不固定参数数量的函数(如 sum(...args)),可以通过显式调用空参数结束柯里化:

function infiniteCurry(fn) {
  return function curried(...args) {
    if (args.length === 0) {
      return fn.apply(this, []);
    } else {
      return function (...nextArgs) {
        if (nextArgs.length === 0) {
          return fn.apply(this, args);
        } else {
          return curried.apply(this, args.concat(nextArgs));
        }
      };
    }
  };
}

使用示例:

function sum(...nums) {
  return nums.reduce((acc, val) => acc + val, 0);
}

const curriedSum = infiniteCurry(sum);
console.log(curriedSum(1)(2)(3)()); // 输出 6
console.log(curriedSum(1, 2)(3, 4)()); // 输出 10

注意事项

  1. 函数长度(fn.length:柯里化依赖函数的形参数量,若使用默认参数或剩余参数(如 function(a, b = 1)),fn.length 可能不准确。
  2. this 绑定:需通过 applycall 确保原函数的 this 上下文正确传递。
  3. 性能:频繁柯里化可能产生大量闭包,需权衡场景需求。

以上实现覆盖了基础柯里化、占位符支持和无限参数场景,可根据实际需求选择或扩展。

标签: 函数柯里
分享给朋友:

相关文章

react函数组件如何混合

react函数组件如何混合

混合 React 函数组件的方法 在 React 中,函数组件可以通过组合、高阶组件(HOC)、自定义 Hook 或 Render Props 等方式实现混合功能。以下是几种常见的方法: 使用自定义…

react如何控制函数组件更新

react如何控制函数组件更新

控制函数组件更新的方法 在React中,函数组件的更新通常由状态(state)或属性(props)的变化触发。以下是几种常见的控制函数组件更新的方法: 使用React.memo进行浅比较 React…

react如何阻止函数组件更新

react如何阻止函数组件更新

阻止函数组件更新的方法 在React中,函数组件的更新通常由状态(state)或属性(props)的变化触发。以下是几种阻止函数组件不必要更新的方法: 使用React.memo进行浅比较 React…

react如何让函数组件缓存

react如何让函数组件缓存

缓存函数组件的常用方法 在React中,函数组件本身是无状态的,但可以通过以下方式实现类似类组件的缓存或优化效果: 使用React.memo进行浅比较缓存 React.memo是一个高阶组件,它会记…

react函数组件如何销毁组件

react函数组件如何销毁组件

在 React 函数组件中销毁组件 React 函数组件的销毁通常由 React 的声明式渲染机制自动处理。当组件从 DOM 中移除时,React 会自动清理其资源。以下是关键点: 触发组件销毁的条…

react函数组件如何强制刷新

react函数组件如何强制刷新

强制刷新React函数组件的方法 在React函数组件中,强制刷新通常不推荐直接操作,因为React的设计理念是基于状态和props的自动更新。但在某些特殊情况下,可能需要手动触发更新。以下是几种常见…