柯里化
比如想要个函数计算一个月一共花了多少钱:
let sumMoney=0;
function cost(money){
sumMoney+=money;
}
cost(100);
cost(50);
cost(200);
// 剩下的调用函数此处省略
console.log(sumMoney);
但实际上,我们并不希望这个cost函数执行31次,而是只在月底的时候执行1次。
改进:
(假设 参数为空就是到月底了)
let cost = (function () {
let arg = [];
return function () {
if (arguments.length === 0) {
let money = 0;
for (let i = 0; i < arg.length; i++) {
money += arg[i];
}
return money;
} else {
[].push.apply(arg, arguments);
}
}
})();
cost(100);
cost(50);
cost(200);
console.log(cost());
柯里化:
function cost() {
let money = 0;
for (let i = 0; i < arguments.length; i++) {
money += arguments[i];
}
return money;
}
let currying = function (fn) {
let arg = [];
return function () {
if (arguments.length === 0) {
return fn.apply(this, arg);
} else {
[].push.apply(arg, arguments);
}
}
};
cost = currying(cost);
console.log(cost(100));
console.log(cost(50));
console.log(cost(200));
console.log(cost());
柯里化:
(不再依赖参数为空再累加)
function cost() {
let money = 0;
for (let i = 0; i < arguments.length; i++) {
money += arguments[i];
}
return money;
}
let currying = function (fn) {
let arg = [];
return function () {
[].push.apply(arg, arguments);
return fn.apply(this, arg);
}
};
cost = currying(cost);
console.log(cost(100));
console.log(cost(50));
console.log(cost(200));
console.log(cost());
反柯里化
比如Array.prototype.push()这个方法,但是它的作用对象是数组,
通过.call()改变它的作用对象,让它为一个对象或类数组对象。
通过call或apply的方式,更改当前的调用者,有没有一种方式让当前的函数不局限于当前的调用者本身,让函数更具有通用性。
Function.prototype.uncurrying = function() {
let fn = this;
return function () {
let _this = Array.prototype.shift.call(arguments);// this是arguments的第一个参数
return fn.apply(_this,arguments);
}
}
let push = Array.prototype.push.uncurrying(); // 它是函数的方法,函数是个实例对象,就需要在Function.prototype上绑定方法
let obj = {};
console.log(push(obj, 'first', 'second'));
console.log(obj);