目的
// 需要柯里化的函数
function sum(a, b, c) {
return a + b + c
}
// 柯里化函数
const curry = function() {
}
// 目的
let a1 = curry(sum)(4)(5)(6) // 10
let a2 = curry(sum, 4, 5)(6) // 10
let a3 = curry(sum)(4)(5, 6) // 10
let a4 = curry(sum,4)(5)(6) // 10
...
实现
第一步
const curry = function() {
}
/* 考虑
* let a2 = curry(sum, 4, 5)(6) // 10
* sum参数为函数,形参fn
* 4, 5参数可用arguments解构,形参...args1
*/
const curry = function(fn, ...args1) {
// 函数返回值应为可调用的函数,故return function
// 返回值可传参6
// 6参数可用arguments解构,形参...args2
return function(...args2) {
// 收集所有参数 [...args1,...args2] 并返回函数的执行fn()
let arg = [...args1, ...args2]
return fn(arg)
}
}
第二步
/* 考虑
* let a4 = curry(sum,4)(5)(6) // 10
*/
const curry = function(fn, ...args1) {
return function(...args2) {
/* 收集参数arg
* 判断参数是否收集完毕arg.length === fn.length
* fn.length为函数sum的形参个数(a, b, c)
* 参数收集完毕,执行函数sum
* 参数没有收集完毕,则继续收集。
* curry(sum,4)(5)(6)每(x)一次,返回函数执行一次,参数(args2)就收集一次
* return都为函数的执行
*/
let arg = [...args1, ...args2]
if (arg.length === fn.length) {
return fn(...arg)
} else {
return curry(fn, ...arg) // arg回传为args1,继续收集参数
}
}
}
// 这里已经完成了
第三步
// 整理
// 合并return值
const curry = function(fn, ...args1) {
return function(...args2) {
let arg = [...args1, ...args2]
return function(...args3) {
// args3 === arg
return args3.length === fn.length
? fn(...arg)
: curry5(fn, ...arg)
}(arg)
}
}
// 去掉临时变量 let arg = [...args1, ...args2]
const curry = function(fn, ...args1) {
return function(...args2) {
return function(...args3) {
// args3===[...args1,...args2]
return args3.length === fn.length
? fn(...args3)
: curry5(fn, ...args3)
}(...args1, ...args2)
}
}
最终版
// 换成箭头函数
const curry = (fn, ...args1) => (...args2) => (
arg3 => arg.length === fn.length
? fn(...arg3)
: curry(fn, ...arg3)
)([...args1, ...args2])