Skip to content

柯里化

js
function curry(fn, args) {
  var length = fn.length;
  var args = args || [];
  return function () {
    newArgs = args.concat(Array.prototype.slice.call(arguments));
    console.log(newArgs);
    if (newArgs.length < length) {
      return curry.call(this, fn, newArgs);
    } else {
      return fn.apply(this, newArgs);
    }
  };
}

function multiFn(a, b, c) {
  return a * b * c;
}

var multi = curry(multiFn);

multi(2)(3)(4);
multi(2, 3, 4);
multi(2)(3, 4);
multi(2, 3)(4);

ES6 写法

js
const curry =
  (fn, arr = []) =>
  (...args) =>
  (arg) =>
    arg.length === fn.length ? fn(...arg) : curry(fn, arg)([...arr, ...args]);

let curryTest = curry((a, b, c, d) => a + b + c + d);
curryTest(1, 2, 3)(4); //返回10
curryTest(1, 2)(4)(3); //返回10
curryTest(1, 2)(3, 4); //返回10

柯里化加闭包

js
// 实现一个add方法, 使计算结果能够满足以下预期
add(1)(2)(3) = 6
add(1,2,3)(4) = 10
add(1)(2)(3)(4)(5) = 15
js
function add(...args) {
  // 累加当前的参数
  let sum = args.reduce((acc, cur) => acc + cur, 0);

  // 返回一个函数,用于后续调用
  function innerAdd(...innerArgs) {
    // 累加新的参数
    sum += innerArgs.reduce((acc, cur) => acc + cur, 0);
    // 返回自身,使得可以继续调用
    return innerAdd;
  }

  // 重写 innerAdd 的 toString 方法,以便在需要时返回结果
  innerAdd.toString = function() {
    return sum;
  };

  // 或者重写 innerAdd 的 valueOf 方法
  innerAdd.valueOf = function() {
    return sum;
  };

  return innerAdd;
}

// 使用示例
console.log(add(1)(2)(3).toString()); // 6
console.log(add(1, 2, 3)(4).toString()); // 10
console.log(add(1)(2)(3)(4)(5).toString()); // 15