柯里化函数理解

来源:互联网 发布:广西广电网络投诉 编辑:程序博客网 时间:2024/06/18 16:23

对柯里化函数理解

curring 的代码解析

代码出自书籍《JavaScript设计模式与开发模式》。

在这之前我大概介绍下什么是 函数柯里化

currying 又称为部分求值。一个 currying 的函数首先会接受一些参数,接受了这些参数之后, 该函数并不会立即求值,而是继续返回另外一个函数,刚才传入的参数在函数形成的闭包中被保 存起来。待到函数被真正需要求值的时候,之前传入的所有参数都会被一次性用于求值。(摘自《JavaScript设计模式与开发模式》)

var currying = function( fn ){    var args = [];    return function(){        if ( arguments.length === 0 ){            return fn.apply( this, args );        }else{            [].push.apply( args, arguments );            //使用了apply,其实相当于 args.push(arguments[0], arguments[1],...);            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 ); // 转化成 currying 函数cost( 100 ); // 未真正求值cost( 200 ); // 未真正求值cost( 300 ); // 未真正求值alert ( cost() ); // 求值并输出:600

curring 函数,首先通过闭包定义了一个私有变量 args,它是用于存储传入的参数的。

当 curring 函数被传入一个回调函数(函数作为参数)时,它会返回一个会执行会用到这个回调函数的函数。

返回的函数里面会保存一个私有变量 arg。

然后有个分支条件,当有参数传入时,会把参数保存到 arg 数组里,并返回原数组;如果没有参数的话,就将 arg 数组作为参数调用回调函数。这里代码是将数组里面的数值进行累加。

你还可以这样使用 cost 函数:

cost(100)(200,300)()

但上面的代码有个缺陷,使用了cost()后,第二次使用cost() 总数将会乘以2,因为money是私有变量,每次计算后,money都会被修改。

解决方法:把 money 不当做私有变量,放到return 里面就可以了。