【JavaScript基础】柯里化 fn(1)(2)(3).val

75 阅读1分钟

Currying 为实现多参函数提供了一个递归降解的实现思路——把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数,在某些编程语言中(如 Haskell),是通过 Currying 技术支持多参函数这一语言特性的。

接下来用一个题目来解释:

  • 题目:实现fn(1)(2)(3).val // 6

简单实现方式: js中,一切皆为对象,可以给fn函数,添加变量val,再来控制其变化;

var fn = (val) => {
  fn.val += val;
  return fn;
};

fn.val = 0;
console.log(fn(1)(2)(3).val); //6
console.log(fn(1).val); //7 --> 存在问题

存在问题: 因为fn.val是全局变量,所以fn每一次调用,都会进行累加; 解决方案: 在fn()方法中包含一个方法f,试每一个fn都存在自己的一个独立变量

var fn = (val) => {
  let f = (x) => {
    f.val += x;
    return f
  };
  f.val = val;
  return f;
};

console.log(fn(1)(2)(3).val); //6
console.log(fn(1).val); //1

至此,就可以实现fn(1)(2)(3).val的方法了,但如果我们进阶一步怎么办嘞?

进阶实现: fn(1,2)(3).val = 6 实现方案: 利用es6的解构函数,argument

function fn() {
  let arr = [...arguments];
  let sum = (array) => {
    return array.reduce((pre, cur) => pre + cur, 0);
  };

  // 因为fn使用了默认arguments
  // 所以此处要使用...args传入参数
  function f(...args) {
    f.val += sum([...args]);
    return f;
  }
  // 因为要先初始化function f,再使用f
  // 所以放在function f()后面
  f.val = sum(arr);
  return f;
}

console.log(fn(1)(2)(3).val);
console.log(fn(1).val);

Tips:箭头函数不存在this,没有...arguments