【柯里化】实现 sum 函数

555 阅读2分钟

这是我参与2022首次更文挑战的第14天,活动详情查看:2022首次更文挑战

我是西瓜哥,今天看一道前端的高频面试题。

要求实现 sum 函数可以做到

sum(1)(2)(3)(4)	// 10
sum(1, 2)(3)(4)	// 10
sum(1)(2, 3)(4)	// 10

柯里化

本题考查的是 函数柯里化

柯里化(Currying)是一种技术,能够将原本应该接受多个参数并直接返回结果的函数,改为接受单一参数并返回新函数,这个新函数又可以接受剩余的参数返回又一个新函数,直到触发特定的条件才进行计算拿到最终结果。

简单来说,就是将原来一次性拿到所有参数的方式,改为了一个个拿参数,最后才计算。

题解

代码实现为:

function curry(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn(...args);
    }
    return function(...args2) {
      return curried(...args, ...args2);
    }
  }
}

const _sum = (a, b, c, d) => a + b + c + d;
const sum = curry(_sum);

我们声明一个名为 curry 的通用将函数进行柯里化的函数。

我们第一次调用 sum 时返回新函数 a。

这个新函数 a 调用时,如果参数数量没有达到被柯里化的函数的参数数量,就会再返回一个新的函数 b。

这个函数 b 其实通过闭包的方式,可以访问

  1. 函数 a

  2. 传入函数 a 的参数

当我们再调用函数 b 时,函数 a 和 函数 a 的参数就会和 b 的参数封装在一起,然后再返回一个新的函数 c。

这个动作直到返回的一个函数的形参数量和被柯里化函数的形参数量相同时,才会结束,真正调用原函数。

结尾

说真的,这种看起来可以无限套娃的柯里化函数确实不好理解。此外,柯里化还有一些变形,我们的柯里化函数也要针对做些调整。