JavaScript 高级函数其他应用 uncurrying (2)

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

uncurrying (反柯里化) 的话题来自JavaScript之父Brendan Eich 在2011年发表的一篇 Twitter. 

那么反柯里化函数,从字面讲,意义和用法跟函数柯里化相比正好相反,扩大适用范围,创建一个应用范围更广的函数。使本来只有特定对象才适用的方法,扩展到更多的对象。


以下代码是实现 uncurrying 方式之一:


Function.prototype.uncurrying = function(){
    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, 5);
    console.log(arguments);            //  [ 1,2,3,4,5 ]
})(1,2,3,4)


上面代码我们通过 uncurrying 的方式, Array.prototype.push.call 变成了一个通用的push 函数,这样一来,push 函数的作用 就跟 Array.prototype.push 一样了, 同样不仅仅局限于只操作array对象。


我们也可以一次性把 Array.prototype 上的方法,复制到 array 对象上,同样这些方法可操作的对象也不仅仅局限于 array 对象。


for(var i = 0 , fn ,ary = [ 'push' , 'shift'];  fn = ary[i++]; ){
    Array[ fn ] = Array.prototype[fn].uncurrying();
};
var obj = {
    "length":3,
    "0":1,
    "1":2,
    "2":3
};
Array.push( obj , 4 );    //向对象中添加一个元素
console.log(obj.length);   //4
var first = Array.shift( obj )  //截取第一个元素
console.log(first);       //  1


除了上面的代码实现,下面的代码时是 uncurrying 的另一种实现方式。


Function.prototype.uncurrying = function(){
    var self = this;
    return function(){
        return Function.prototype.call.apply( self , arguments );
    }
}