JavaScript 高级函数其他应用 currying(1)

日期: 2017-08-09         浏览量: 2751

今天我们来学习下高级函数的其他应用:function currying (函数柯里化)


currying 的概念最早是由俄国数学家 Moses Schonfinkel 发明,而后有著名的数学逻辑学家 Haskell Curry 将其丰富和发展,currying 由此得名。


currying 又称部分求值。 一个currying的函数首先会接受一些参数,接受参数后,改函数并不会立即求值,而是继续返回另外一个函数,刚才传进去的参数在函数形成的闭包中被保存起来。待到函数被真正求职的时候之前传入的所有参数都会被一次性用于求值。


从字面上理解并不容易,我们来看个例子。(下面的 cost 函数还不是一个 curring 函数的完整实现, 但有助于我们了解其思想



var cost = (function(){
    var args = [];
 return function(){
        var money = 0;
        if(arguments.length ===0){
                //计算数据值
                for(var i=0, j = args.length; i<j ; i++ ){
                    money += args[i]
                }
                return money;
        }else{
            //不计算数据值,只是保存数据
            Array.prototype.push.apply(args , arguments) 
        }
    }
})()
cost(100);            //未真正求职
cost(300);            //未真正求职
cost();                //真正求职



下面写一个通用的function currying(){} ,function currying(){} 接受一个参数, 即将要被 currying 的函数。在这个例子里,这个函数的作用遍历本月每天的开销并求出它们的总和。

代码如下:


var currying = function( fn ){
    var args = [];
    return function(){
        if( arguments.length === 0){
            return fn.apply( this, args );
        }else{
            Array.prototype.push.apply( args, arguments );
            return arguments.callee;
        }
    }
}

var cost = (function(){
    var money = 0;
    return function(){
        for(var i=0, j = arguments.length; i<j ; i++ ){
              money += arguments[i]
        }
        return money;
    }
})();

var cost = currying( cost );
cost(100);             //未计算
cost(200);             //未计算
cost();                    //求职


至此,我们就完成了一个 currying 函数的编写。当调用cost() 时,如果明确的带上了一些参数,表示此时并不进行真正的求职计算。而是把这些参数保存起来,此时让 cost 函数返回另外一个函数。只有当我们以不带参数的形式执行cost() 函数时 ,才利用前面保存的所有参数,真正开始进行求值计算。