Skip to content

柯里化(Currying)

高阶函数

将函数作为参数或者返回值是函数的函数

  • 例如

简单的分步加法函数

js
function add(a){
    return function(b){
        return a+b
    }
}
let add1 = add(1)
add1(2) === 1+2 // true

es6写法

js
let add = a => b => a + b
  • 再例如
js
function strTools(fn){
    return function(str){
        return fn(str)
    }
}

柯里化

把一个接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回(接受剩下的参数而且返回结果的)新函数的技术。

上面的add例子就是柯里化的一个应用

柯里化后的函数,将第一个参数变量通过闭包存在了函数里面,然后原来需要n个参数的函数变成只需要n-1个参数的函数了

  • 经典的栗子
js
let add = (a, b) => a + b
console.log(add(2,3));//5
console.log(add(2,4));//6
console.log(add(2,5));//7

柯里化后

js
function add(a){
    return function(b){
        return a+b
    }
}
// es6
let add = a => b => a + b

let add2 = add(2)
console.log(add2(3)) // 5
console.log(add2(4)) // 6
console.log(add2(5)) // 7

es6写法中n个连续箭头组成的函数实际上就是柯里化了n-1次

也就是连续箭头函数就是多次柯里化函数的es6写法

js
let test = x => y => z => k => x + y + z + k
console.log(test(1)(2)(3)(4))//10

总结柯里化的功能

  • 惰性求值
  • 可以提前传递部分参数
  • 参数复用

一个通用的封装方法

js
function curry(fn, ...args) {
    return fn.length > args.length ? (...args2) => curry(fn, ...args, ...args2) : fn(...args)
}

function fn(a, b, c, d) {
    console.log(a + b + c + d)
}

fn = curry(fn)
fn(1)(2)(3, 4) // 10