说实话,函数柯里化我真的有点疑惑,一直没有想到合理的应用的场景,于是决定今天老子要吃掉这块肉 ,哼~ 接下来,我们一起来了解一下函数柯里化吧
函数柯里化的概念
curring又称作为部分求值,一个curring的函数首先会接受一些参数,接受了这些参数之后,该函数并不会立即求值,而是继续返回另一个函数,
刚才传入的参数在函数形成的闭包中被保存起来。待到函数被真正需要求值的时候,之前传入的所有参数都会被一次性用于求值。
下面例子为,每天计算开销,月底进行结算,这个只要用于保存参数,或者判断是否需要进行一次性求值.
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 {
Array.prototype.push.apply(args, arguments)
}
}
})()
cost(200)
cost(300)
cost()//500
接下来我们编写一个通用的function curring(){},该函数接收一个参数,即将要被curring的函数。
var curring = function (fn) {
var arg = [];
return function () {
if (arguments.length === 0) {
return arg
}
else {
[].push.apply(arg, arguments);
return arguments.callee // 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 = curring(cost)
cost(300)
uncurring的概念
在javaScirpt中,当我们调用对象的某个方法时,其实不用去关心该对象原本是否被设计为拥有这个方法,这是动态类型的特点,也是常说的鸭子类型思想
一个对象未必只能使用它自身的方法,我们可以使用 call和aplly借用其他不属于自己的方法。
让类数组去借用Array.prototype的方法,是call和apply的常见的应用 ,
这是call和apply的最常用的场景之一
(function() {
Array.prototype.push.call(arguments,4)
console.log(arguments) } )(1,2,3)
我们可以把泛化this的过程提取出来,那么uncurrying
Function.prototype.uncurrying = function () {
console.log(this)//谁调用指向谁
var self = this;
return function () {
var obj = Array.prototype.shift.call(arguments);//传入参数为对象
return self.apply(obj, arguments)//传入参数为数组
}
};
var push = Array.prototype.push.uncurrying();
(function () {
push(arguments, 4);
console.log(arguments,'arguments');
})(1, 2, 3)
常用的函数柯里化的场景
柯里化常见的作用的是什么呢?常见的作用是:
参数复用
延迟运行
扁平化
var curry = function (fn) {
var args = [].slice.call(arguments, 1)
console.log(args,arguments)
return function () {
var newArgs = args.concat([].slice.call(arguments))//这句话有什么存在的意义????
console.log([].slice.call(arguments),"argssssss")
console.log(newArgs,"newArgs")
return fn.apply(this, newArgs)
}
};
function add(a, b) {
return a + b
};
var addCurry = curry(add, 1, 2);
addCurry(); // 3