当前位置:首页 > 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. 性能:频繁柯里化可能产生大量闭包,需权衡场景需求。

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

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

相关文章

vue防抖函数实现

vue防抖函数实现

防抖函数原理 防抖(Debounce)是一种限制函数频繁调用的技术,在事件被触发后延迟执行,若在延迟时间内再次触发,则重新计时。适用于输入框搜索、窗口大小调整等场景。 Vue 中实现防抖的三种方式…

react如何定义全局函数

react如何定义全局函数

定义全局函数的几种方法 在React中定义全局函数可以通过多种方式实现,以下是常见的几种方法: 使用全局变量挂载 将函数直接挂载到window对象上,使其成为全局可访问的函数。这种方式简单直接,但…

react如何绑定事件处理函数

react如何绑定事件处理函数

在 React 中绑定事件处理函数的方法 React 提供了多种方式来绑定事件处理函数,以下是常见的几种方法: 使用箭头函数自动绑定 this 在类组件中,可以使用箭头函数来定义方法,这样可以避免…

react如何阻止函数组件更新

react如何阻止函数组件更新

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

react函数组件如何销毁事件

react函数组件如何销毁事件

在 React 函数组件中销毁事件 React 函数组件中需要手动销毁事件监听或定时器,以避免内存泄漏和性能问题。以下是几种常见情况的处理方法: 使用 useEffect 清理副作用 在函数组件中,…

react函数组件如何销毁组件

react函数组件如何销毁组件

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