面试也需要考笔试题: 实现 JavaScript 柯里化函数

84 阅读2分钟

柯里化(Currying)是指将一个接受多个参数的函数转化为一个接受单一参数的函数,并且返回一个函数序列的技术。最终这些函数序列可以接收剩余的参数,然后返回结果。

实现一个简单的柯里化函数

下面是一个通用的 JavaScript 柯里化函数实现:

function curry(fn) {
    // 获取函数所需的参数个数
    const arity = fn.length;

    // 内部递归函数,用于逐步收集参数
    return function curried(...args) {
        // 如果传入的参数数量已经足够
        if (args.length >= arity) {
            // 调用原始函数并传递所有参数
            return fn(...args);
        } else {
            // 返回一个新函数,用于收集更多参数
            return function(...moreArgs) {
                // 递归调用 curried 函数,继续收集参数
                return curried(...args, ...moreArgs);
            };
        }
    };
}

使用示例

假设我们有一个简单的函数 add,它接受三个参数并返回它们的和:

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

我们可以使用 curry 函数将 add 函数进行柯里化:

const curriedAdd = curry(add);

// 现在可以逐步调用 curriedAdd 函数
console.log(curriedAdd(1)(2)(3)); // 输出 6

// 也可以一次性传递所有参数
console.log(curriedAdd(1, 2, 3)); // 输出 6

// 或者部分应用参数
console.log(curriedAdd(1, 2)(3)); // 输出 6

代码详解

  1. curry 函数

    • 接受一个函数 fn 作为参数。
    • 使用 fn.length 获取函数 fn 的形参个数,即需要多少个参数才能调用这个函数。
  2. curried 函数

    • 这是一个内部递归函数,它使用 ...args 收集传递的参数。
    • 如果 args.length 与函数的 arity 相同或更多,则直接调用 fn 并传递所有收集到的参数。
    • 否则,返回一个新函数,该函数继续收集更多的参数。
  3. 递归调用

    • curried 函数通过递归的方式收集参数,直到参数的数量满足原始函数 fn 的要求。

通过这种方式,我们实现了一个可以逐步接收参数的柯里化函数,非常适合在函数式编程中应用。