自动柯里化函数

454 阅读2分钟

自动柯里化函数的功能

  1. 将普通函数柯里化,返回柯里化后的函数。
//函数功能:将普通函数变为柯里化函数
function change(fn) {
  //返回包装后的函数。
  const resultFn = function (...args) {
    //实参的长度大于形参的长度表示接受参数完毕,则调用函数。
    if (args.length >= fn.length) {
      //需要显示绑定this。让fn的this和resultFn的this一样。即包装后的函数的this给原函数。
      return fn.apply(this, args);
    } else {
      //参数没有接受完毕,返回其他函数继续接受参数。
      return function (...restArgs) {
        //递归判断。当执行该函数时,会递归调用resultFn,从而判断参数是否接受完毕,进行后续操作。
        return resultFn.apply(this, [...args, ...restArgs]);
      };
    }
  };
  return resultFn;
}

//普通函数
function sum(x, y, z) {
  return x + y + z;
}
//柯里化函数
const newSum = change(sum);
//测试代码
console.log(newSum(1)(2)(3)); //6
console.log(newSum(1, 2)(3)); //6
console.log(newSum(1, 2, 3)); //6

自动柯里化函数的不足之处

//普通函数
function sum(x, y, z) {
  console.log("x的逻辑操作");
  console.log("y的逻辑操作");
  console.log("z的逻辑操作");
  return x + y + z;
}

//自动柯里化函数
const newSum = change(sum);
const add5 = newSum(5);
//测试代码
//xyz的逻辑处理执行多次
console.log(add5(1)(2));
console.log(add5(10)(20));

//手动柯里化函数
const changeSum = function (x) {
  console.log("x的逻辑操作");
  return function (y) {
    console.log("y的逻辑操作");
    return function (z) {
      console.log("z的逻辑操作");
      return x + y + z;
    };
  };
};
const add10 = changeSum(10); //x的逻辑处理只会执行一次
//测试代码
console.log(add10(1)(2));
console.log(add10(10)(20));
  1. 只是调用方式变得柯里化了。前期利用闭包收集参数,在最后一步执行原函数。
  2. 真正的柯里化函数,是可以逻辑复用的。即逻辑复用那部分可以不需要重复调用,直接使用第一次调用的结果即可。
  3. 如果不在乎逻辑处理是否执行多次,那么在代码形式上(编写代码时不需要每次传固定的参数),也可以认为自动柯里化函数实现了逻辑复用。

自动柯里化函数涉及到的知识汇总

  1. 闭包。函数引用外部变量。
  2. 实参、形参、剩余参数的个数判断。(arguments、函数.length、...args)
  3. this的指向。原函数在执行时,往往需要将this绑定为包装函数的this。
  4. 递归。(在不确定层级或循环次数时,使用递归或while循环。)
  5. 柯里化的概念及优势。(优势:函数职责单一、逻辑复用。)