函数柯里化
假设我们要编写一个记录每月开销的函数。如果在每个月的前29天,我们都只是保存当天的开销,直到第30天才进行求值计算。
var cost = (function(){
var args = [];
return function() {
if (arguments.length == 0) {
var money = 0;
for (var i = 0,l = args.length; i < l; ++i) {
money += args[i];
}
return money;
} else {
[].push.apply(args,arguments);
}
};
})();
cost(100); // 未真正求值
cost(200); // 未真正求值
cost(300); // 未真正求值
console.log(cost()); //求值并输出 600
接下来,编写一个通用的function currying(){}
var currying = function(fn) {
var args = [];
return function() {
if (arguments.length == 0) {
return fn.apply(this,args);
} else {
[].push.apply(args,arguments);
return arguments.callee;
}
};
};
var cost = (function() {
var money = 0;
return function() {
for (var i = 0,l = arguments.length; i < l; ++i) {
money += arguments[i];
}
return money;
};
})();
var cost = currying(cost);
cost(100); // 未真正求值
cost(200); // 未真正求值
cost(300); // 未真正求值
console.log(cost()); // 求值并得到600
反柯里化
Function.prototype.uncurrying = function() {
var self = this; // self此时是Array.prototype.push
return function() {
var obj = Array.prototype.shift.call(arguments);
// obj是
// {
// "length" :1,
// "0": 1
//}
// arguments对象的第一个元素被截去,剩下[2]
return self.apply(obj,arguments);
// 相当于Array.prototype.push
};
};
var push = Array.prototype.push.uncurrying();
var obj = {
"length": 1,
"0": 1
};
push(obj,2);
console.log(obj); //{ '0': 1, '1': 2, length: 2 }
uncurrying的另一种实现:
Function.prototype.uncurrying = function() {
var self = this; // 保存原函数
return function () {
return Function.prototype.call.apply(self,arguments);
};
}
我的理解是柯里化可以积累数据之后再计算,
反柯里化 根据已有的函数转化为特殊需求的函数(可能是参数的格式)
可以参考函数柯里化&&反柯里化