// 利用reduce实现多参数版add
let add = function(...args){
return args.reduce(function(accumulator, currentValue) {
return accumulator + currentValue;
},0)
};
// 一个简单的currying实现
function currying(func) {
const args = [];
return function result(...rest) {
if (rest.length == 0) {
return func(...args);
} else {
args.push(...rest);
return result;
}
}
}
let sum = currying(add);
sum(1)(2)(3); //未真正执行求和运算
sum(4); //未真正执行求和运算
sum(); //执行求和
Function.prototype.bind = function (context) {
var _this = this;
var args = Array.prototype.slice.call(arguments, 1);
return function() {
return _this.apply(context, args);
}
}
// 初步的柯里化函数,其中fn是即将被柯里化的函数
var primaryCurrying = function (fn,...args) {
return function (...args2) {
// 将以后传给这个闭包函数里的全部参数和之前的args进行合并
var newArgs = args.concat(args2);
// 把合并后的参数通过apply作为fn的参数并执行
return fn.apply(this, newArgs);
}
}
function add(a, b) {
return a + b;
}
var add1= primaryCurrying(add, 1);
var result = add1(2);
console.log(result); //>> 3
var curry = primaryCurrying(add);
var add = curry(1,2);
console.log(add);//>> 3
var add = curry(1)(2);
console.log(add); //>> TypeError: curry(...) is not a function
// 借用之前的初步柯里化函数,让柯里化后的函数fn有多1段的能力。
var primaryCurrying = function (fn,...args) {
return function (...args2) {
var newArgs = args.concat(args2);
return fn.apply(this, newArgs);
}
}
/**
* 设计真正的柯里化函数。
* @param fn 即将被柯里化的函数。
* @param length 用来记录fn应该处理的剩余参数的长度。
*/
function curry(fn, length) {
length = length || fn.length;
return function (...args2) {
//若原本要传给fn的参数还未传完
if (args2.length < length) {
//合并参数
var combinedArgs = [fn].concat(args2);
//递归,进一步柯里化。这里调用了primaryCurrying函数,每调用一次该函数,
//就可以多“1段”以便可以处理掉剩余的参数,直到把所有应传给fn的参数都处理完。
return curry(primaryCurrying.apply(this, combinedArgs), length - args2.length);
}
//若原本要传给fn的参数都已经传完,则直接执行fn函数
else {
return fn.apply(this, args2);
}
};
}