函数柯里化

区分一下 高阶函数和函数柯里化的概念


高阶函数:1)函数可以作为参数 2)函数可以作为返回值

我们平时使用的setTimeout,map,filter,reduce等都属于高阶函数,当然还有我们今天要说的函数的柯里化,也是高阶函数的一种应用

柯里化:

它用于创建已经设置好了一个或多个参数的函数。函数的柯里化的基本使用方法和函数绑定是一样的:使用一个闭包返回一个函数。两者的区别在于,当函数被调用时,返回的函数还需要设置一些传入的参数,总之函数的柯里化就是将多参数函数转换成单参数函数,这里的单参数并不仅仅指的是一个参数


具体实现:

function currying(fn, length) {
  length = length || fn.length; 	// 注释 1
  return function (...args) {			// 注释 2
    return args.length >= length	// 注释 3
          	? fn.apply(this, args)			// 注释 4
            : currying(fn.bind(this, ...args), length - args.length) // 注释 5
        }
      }


注释:

  • 注释 1:第一次调用获取函数 fn 参数的长度,后续调用获取 fn 剩余参数的长度
  • 注释 2:currying 包裹之后返回一个新函数,接收参数为 ...args
  • 注释 3:新函数接收的参数长度是否大于等于 fn 剩余参数需要接收的长度
  • 注释 4:满足要求,执行 fn 函数,传入新函数的参数
  • 注释 5:不满足要求,递归 currying 函数,新的 fn 为 bind 返回的新函数(bind 绑定了 ...args 参数,未执行),新的 length 为 fn 剩余参数的长度



const currying = fn =>
    judge = (...args) =>
        args.length >= fn.length
            ? fn(...args)
            : (...arg) => judge(...args, ...arg)



es5


function currying(fn) { 
  let args = []; 
  return function closureFn() { 
    args = args.concat(Array.from(arguments)); 
    if (args.length < fn.length) return closureFn; 
    const res = fn.apply(this, args); 
    args = []; return res; 
  }
} 
const sum = currying((a, b) => a + b); 
console.log(sum(1, 2) === sum(1)(2)); 


参考:【github】

确认 取消