zlx362211854 / daily-study

每日一个知识点总结,以issue的形式体现
10 stars 6 forks source link

60. 柯里化 #99

Open goldEli opened 5 years ago

goldEli commented 5 years ago
  1. 柯里化有什么用?
  2. 自己实现柯里化方法,完善下面的代码。
const curry = (func) => {
  // code some stuff
}

const func = (a,b,c) => {
  return a+b+c
}

curry(func)(1)(2)(3)
// => 6
curry(func)(1,2,3)
// => 6
curry(func)(1,2)(3)
// => 6
nanslee commented 5 years ago
/*
* 柯里化允许一个函数接收多个参数,可根据不同的实际场景对公共代码进行复用从而减少
* 代码冗余,举个例子比如拼接不同接口的 url,如果前缀都是 https://10.0.10.5/api/.../...
* 那么可以抽取公共部分,自由组合不同 url,增加代码可读性
*/

const curry = func => {
  function next(...args) {
    if (func.length === args.length) {
      return func(...args);
    }
    return function(...newArgs) {
      return next(...args, ...newArgs);
    };
  }
  return next;
};

const fun = (a, b, c) => {
  return a + b + c;
};

console.log(curry(fun)(1)(2)(3));
// => 6
console.log(curry(fun)(1, 2, 3));
// => 6
console.log(curry(fun)(1, 2)(3));
// => 6
goldEli commented 5 years ago

柯里化主要用来封装参数,提高函数的复用性以及函数的可阅读性。

比如:

// 这是一个计算商品价格的函数,有两个参数,折扣和价格。
function calculate(discount, price){}

// 当用户购买一件价格为100元,九折的商品调用该方法:
calculate(0.9, 100)

// 如果这个月所有商品都是九折
// 那么每次计算用户消费时,都会重复的传入 0.9 这个参数
// 我们可以用柯里化把这个参数封装起来,得到一个计算九折商品的函数
var tenPercentOff = curry(calculate)(0.9)

// 之后所有的计算,只用调用 tenPercentOff 传入商品价格就可以了
// 同理我们还可以封装计算八折、七折商品的函数...

柯里化实现


const curry = func => {
  const loop = (...args) => {
    return args.length === func.length
      ? func(...args)
      : (...newArgs) => loop(...args, ...newArgs)
  }
  return loop
}

const func = (a,b,c) => {
  return a+b+c
}

curry(func)(1)(2)(3)
// => 6
curry(func)(1,2,3)
// => 6
curry(func)(1,2)(3)
// => 6
zlx362211854 commented 5 years ago
var currying = function(fn) {
  function again(...args) {
    if (fn.length === args.length) {
      fn.apply(this, args)
    } else {
      (...newArgs) => again(args, newArgs)
    }
  }
  return again
}