likes
comments
collection
share

柯里化其实就是这么回事,别被高大上的名词骗了——拒绝“八股文”

作者站长头像
站长
· 阅读数 66

什么是函数柯里化

函数柯里化 (Currying) 是一种将多个参数的函数转换为单个参数函数的技术,通过使用函数柯里化,可以提高代码的复用性和可维护性

举个例子,有一个求两数之和的函数:

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

如果把这个函数柯里化,就会变成:

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

再来看一个例子,有一个求两数相乘并加上偏移量的函数:

function multiplyAndOffset(a, b, offset) {
  return a * b + offset;
}

我们可以把这个函数柯里化为:

function multiply(a) {
  return function(b) {
    return function(offset) {
      return a * b + offset;
    }
  }
}

使用柯里化之后,我们就可以这样调用:

multiply(2)(3)(1); // 7

为什么需要函数柯里化

函数柯里化在实际开发中有很多好处:

  • 函数复用:由于函数柯里化的特性,我们可以非常容易地为函数的一部分参数进行复用。例如,上面那个例子中的 multiply 函数,如果我们想要使用相同的 offset 参数,在调用时只需要传递两个参数就可以了
  • 延迟执行:柯里化使得函数的执行被延迟到最后一个参数被传递进来的时候再进行。这使得我们可以预先传递一些参数,并将剩余的参数留到稍后再决定,这在一些场景下非常有用,例如事件处理程序
  • 简单化函数:由于柯里化把多参数函数转化成了单参数函数,这使得函数接口更加简洁,更加容易使用
  • 函数组合:函数柯里化可以使得不同的函数更加容易组合起来使用,从而实现更加复杂的操作

如何实现函数柯里化

函数柯里化的本质就是通过闭包来返回一个函数,这个返回的函数会接收一个新的参数并返回一个新函数,这个新函数会再次接收一个参数并返回一个新的函数,以此类推直到最后一个参数被传递进来

下面是一个实现柯里化的简单示例:

    function add() {
      let sum = 0;
      return function innerFn(num) {
        if (num !== undefined) {
          sum += num;
          return innerFn;
        } else {
          return sum;
        }
      }
    }

    console.log(add()(1)(2)(3)()); // 输出 6

我们首先定义了一个 add 函数,它返回了一个内部函数 innerFn。在 innerFn 中,我们首先定义了一个变量 sum,用于保存累加的结果。当传入的参数不为 undefined 时,我们将其加到 sum 中,并返回 innerFn。这样就可以继续传递下一个参数了。当参数为 undefined 时,我们返回 sum,表示累加完毕

但是,这种简单的实现方式存在一个问题,那就是只能处理参数数量为 2 的函数,无法处理参数数量不确定的函数。因此我们需要更加通用的柯里化实现方式

这里是一个更加通用的函数柯里化的实现方式:

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

该函数的参数是一个函数 fn,它返回一个柯里化后的函数。在函数内部,我们定义了一个 curried 函数,它的作用是接受函数需要的所有参数。当传入的参数数量大于或等于原函数需要的参数数量时,就直接调用原函数并返回结果;否则,返回一个新函数,然后使用闭包将当前已经传入的参数保存下来。这个新函数再次接受一个参数,并将这个参数与之前已经保存的参数合并,然后递归调用 curried 函数

我们可以使用如下方式调用 curry 函数:

    const add = (a, b, c) => a + b + c;
    const curriedAdd = curry(add);
    console.log(curriedAdd(1)(2)(3)); // 6
    console.log(curriedAdd(1, 2)(3)); // 6
    console.log(curriedAdd(1)(2, 3)); // 6
    console.log(curriedAdd(1, 2, 3)); // 6

这个函数柯里化实现方式比较通用,可以处理多种不同参数数量的函数

结语

函数柯里化是一种非常有用的编程技术,它可以提高代码的复用性、简化函数接口、延迟函数执行等。在实际开发中,我们可以使用函数柯里化来实现部分应用函数,处理数据,编写事件处理程序等。同时,我们也需要注意柯里化函数的性能问题,在一些大量调用的场景下需要注意函数执行次数以及闭包变量的使用,避免出现性能瓶颈

我是前端霸哥,愿你的代码中没有bug 写的不好的地方,欢迎各位小伙伴批评指正

转载自:https://juejin.cn/post/7242942636247269431
评论
请登录