当前位置:首页 > JavaScript

js curry实现

2026-03-14 01:12:34JavaScript

柯里化(Currying)的概念

柯里化是一种将多参数函数转换为一系列单参数函数的技术。例如,一个接受三个参数的函数 f(a, b, c) 柯里化后会变为 f(a)(b)(c)。柯里化的核心是延迟执行,逐步传递参数。

实现基础柯里化

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

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

示例用法:

function sum(a, b, c) {
    return a + b + c;
}
const curriedSum = curry(sum);
console.log(curriedSum(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 = '_';

示例用法:
```javascript
function sum(a, b, c) {
    return a + b + c;
}
const curriedSum = curryWithPlaceholder(sum);
console.log(curriedSum('_', 2)(1, 3)); // 输出 6(跳过第一个参数,后续补充)

无限参数柯里化

若需支持不固定参数数量的柯里化(如累加),需明确终止条件(如无参数调用):

function infiniteCurry(fn) {
    return function curried(...args) {
        if (args.length === 0) {
            return fn();
        } else {
            return function(...nextArgs) {
                if (nextArgs.length === 0) {
                    return fn(...args);
                } else {
                    return curried(...args, ...nextArgs);
                }
            };
        }
    };
}

示例用法:

js curry实现

const add = infiniteCurry((...nums) => nums.reduce((a, b) => a + b, 0));
console.log(add(1)(2)(3)()); // 输出 6(通过空调用终止)

注意事项

  • 参数长度检查:基础柯里化依赖 fn.length,因此不适用于可变参数函数(如 (...args) => ...)。
  • 性能:每次柯里化调用会生成新函数,可能带来轻微性能开销。
  • 上下文:使用 apply 确保函数调用时的 this 正确绑定。

标签: jscurry
分享给朋友:

相关文章

js实现继承

js实现继承

原型链继承 通过将子类的原型指向父类的实例实现继承。子类实例可以访问父类原型上的属性和方法。 function Parent() { this.name = 'parent'; } Parent…

原生js实现轮播图

原生js实现轮播图

基本结构搭建 HTML部分需要包含轮播图容器、图片列表及导航按钮。结构示例如下: <div class="slider-container"> <div class="slid…

js实现拷贝

js实现拷贝

实现文本拷贝 使用 document.execCommand 方法(已废弃但兼容性较好): function copyText(text) { const textarea = document…

js实现瀑布流

js实现瀑布流

实现瀑布流布局 瀑布流布局是一种常见的网页布局方式,常用于图片展示、商品列表等场景。以下是使用 JavaScript 实现瀑布流布局的几种方法。 纯 JavaScript 实现 通过计算元素的位置和…

js 实现链表

js 实现链表

链表的基本概念 链表是一种线性数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。与数组不同,链表在内存中是非连续存储的,插入和删除操作效率较高。 链表的实现 在 JavaScrip…

js实现二叉树

js实现二叉树

二叉树的基本概念 二叉树是一种树形数据结构,每个节点最多有两个子节点,分别称为左子节点和右子节点。二叉树的常见操作包括插入、删除、遍历等。 二叉树的节点定义 在JavaScript中,二叉树的节点可…