1柯里化
https://segmentfault.com/a/1190000018180159
柯里化函数的精髓
利用了以下几点
- 函数的参数接受多余的参数,多余的可以被arguments接受,arguments是一个伪数组。
- [].slice.call(arguments);[]只要是数组即可,eg[12,9],aruments是类数组。依据arguments,返回一个真正的数组。写成Array.prototype.slice.call也可以
- fn.length为声明时参数的个数
核心:拼接参数为args,判断参数args,是否等于fn.length为声明时参数的个数,若不等于,返回curry (fn, args),若等于,返回fn.apply(null,args)
curry(add,[1,2])返回的是内部的function(){…},被变量curryAdd 接收,形成闭包,这个function没有执行。
curry(add,[1,2])(3),相当于把3传入这个返回的函数,并执行。
function curry(cb)
{
return function(x){
return function (y) {
return cb(x,y)
}
}
}
function add(x,y) {
return x+y
}
let curryAdd = curry(add)
console.log(curryAdd(1)(2))//3
function curry (fn, currArgs) {
return function() {
console.log('exe');
let args = [55,66].slice.call(arguments);
// 首次调用时,若未提供最后一个参数currArgs,则不用进行args的拼接
if (currArgs !== undefined) {
// console.log(typeof currArgs);
args = typeof currArgs=='number'?[currArgs]:currArgs.concat(...args);
}
if (args.length < fn.length) {
console.log(args);
return curry(fn, args);
}
console.log(args);
// args.reverse()
return fn.apply(null, args);
}
}
}
function add(x,y,z) {
return x-y-z
}
let curryAdd = curry(add,[1,2])
console.log(curryAdd(3));//-4
2 偏函数
冻结一步分参数,释放另一部分参数。柯里化是 参数一步一步传入。
补充 使用扩展运算符
柯里化es6
function curry(fn,...oldargs) {
return function (...newargs) {
newargs = oldargs.concat(newargs)
if (newargs.length < fn.length) {
return curry(fn,...newargs)
}
else return fn.call(null,...newargs)
}
}