JavaScript 柯里化

柯里化的表现:把原先接受多个参数的函数转化为只接受一个参数的函数。

柯里化带来的作用:

  • 参数复用
  • 延迟执行
  • 提前返回
function sum(x, y, z) {
  return x + y + z;
}

// 通用的柯里化函数
function curry(func) {
  // 传入一个函数后返回一个函数
  return function curried(...args) {
    if (args.length >= func.length) {
      return func.apply(this, args);
    } else {
      return function(...args2) {
        return curried.apply(this, args.concat(args2)); // 最终执行初次传入的函数,并将所有参数丢给它
      }
    }
  };
}

let curriedSum = curry(sum);

alert( curriedSum(1, 2, 3) ); // 6, still callable normally
alert( curriedSum(1)(2,3) ); // 6, currying of 1st arg
alert( curriedSum(1)(2)(3) ); // 6, full currying

curry(sum)执行后返回一个函数,以 curriedSum(1)(2,3) 为例,实际就是curried(1)

function curried(...args) {
    if (args.length >= func.length) {
      return func.apply(this, args);
    } else {
      return function(...args2) {
        return curried.apply(this, args.concat(args2)); // 最终执行初次传入的函数,并将所有参数丢给它
      }
    }
  };

curried(1) // 第一个参数被执行 --> 发现参数个数小于最开始定义的 sum 函数的参数 --> 再返回一个函数,此时这个函数执行的入参为 (2,3),发现参数个数只有两个,不满足 sum 的参数个数,因而继续返回,同时将之前的入参保留一并传入,此时收集到三个参数,满足 sum 函数的参数个数,因此执行 sum 也就是 func

网上的 toString 写法涉及隐式类型转换,不太好理解,也不推荐,还是参考文章讲解的通俗。

参考文章:

https://javascript.info/currying-partials