什么是柯里化
柯里化是把接受多个参数的函数,变换成接受一个参数的函数,并且返回的函数可以接受剩余的参数,并返回新结果。
下面是求两数之和的例子
var add = function(a, b) {
return a + b;
}
add(3, 4)
我们把它转换成柯理化函数,可以理解为把多个参数的函数, 转化为链式调用的单一参数的函数。
var addCurry = curry(add);
addCurry(1)(2) // 3
实现curry
我们封装了一个 curry函数, 调用curry, 会返回一个包装后的柯理化函数。
function curry(fn) {
return function curried(...args) { //第一次调用addCurry接受的参数
if (args.length >= fn.length) {//直到接受的参数数量达到可以调用 add 函数时,返回调用结果。
return fn.apply(this, args);
} else {
return function (...args2) {//第二次调用addCurry, 如果参数数量未满足, 则返回一个函数, 继续接受参数。
return curried.apply(this, args.concat(args2)); //把参数和上一次的参数拼接在一起。
};
}
};
}
var add = function(a, b, c) {
return a + b + c;
}
var addCurry = curry(add); //转换成柯理化函数
console.log(addCurry(1)(2)(3))
柯理化的应用场景
减少重复参数
function simpleURL(protocol, domain, path) {
return `${protocol}://${domain}/${path}`
}
simpleURL('https', 'www.fxiaoke.com', 'bi')
simpleURL('https', 'www.fxiaoke.com', 'crm')
simpleURL('https', 'www.fxiaoke.com', 'paas')
上面的封装很常用, 可是调用时需要传太多重复的参数, 我们优化一下。
function simpleURL(path) {
return `https://www.fxiaoke.com/${path}`
}
simpleURL('bi')
simpleURL('crm')
simpleURL('paas')
这样优化后, 我们不用每次调用都传不变的参数了, 但是, 如果后面的开发需要我们获取不同域名,怎么办?或者有 http协议呢?我们用柯理化函数来解决这个问题。
function simpleURL(protocol, domain, path) {
return `${protocol}://${domain}/${path}`
}
const urlCurry = curry(simpleURL)('https')('www.fxiaoke.com')
urlCurry('bi')
urlCurry('crm')
urlCurry('pass')
柯理化的缺点
缺点
如果调用链特别长, 会导致内存得不到释放