首页 > 其他 > 详细

反柯里化 - uncurrying

时间:2015-10-14 19:58:10      阅读:324      评论:0      收藏:0      [点我收藏+]

转载:http://www.alloyteam.com/2013/08/javascript-zhong-you-qu-di-fan-ke-li-hua-ji-shu/

反柯里化( uncurrying, 非currying )的话题来自javascript之父Brendan Eich去年的一段twitter. 近几天研究了一下,觉得这个东东非常有意思,分享一下。先忘记它的名字,看下它能做什么.

var obj = {};
var push = Array.prototype.push.uncurrying();
// 代码相当于Array.prototype.push.call( obj, "first");
push( obj, "first"); 
console.log(obj.length);
console.log(obj[0]);

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

不要小看这个功能,试想下,我们在写一个库的时候,时常会写这样的代码,拿webQQ的Jx库举例。

if( Array.prototype.indexOf ) {
     Jx.Array.indexOf = function() {
           var ary = Array.prototype.shift.call( arguments);
            return Array.prototype.indexOf.apply( ary, arguments);
      }
} else {
    // manually implement indexOf for those broswer which didn‘t support Array.prototype.indexOf
}

我们想要的,其实只是借用Array原型链上的一些函数。并没有必要去显式的构造一个新的函数来改变它们的参数并且重新运算。

如果用uncurrying的方式显然更加优雅和美妙,就像这样:

if( Array.prototype.indexOf ) {
    Jx.Array.indexOf = Array.prototype.indexOf.uncurrying();
}

调用方式跟之前一样, Jx.Array.indexOf( [ 1, 2 ,3 ], 2 );
还能做很多有趣和方便的事情.

var slice = Array.prototype.slice.uncurrying();
~function() {
     console.log( slice( arguments, 2 )) // [3,4]
} ( 1,2,3,4)

var type = Object.prototype.toString.uncurrying();
console.log( type( [ 1,2,3 ] )) // [ object Array ] 

甚至还能把call和apply方法都uncurrying,把函数也当作普通数据来使用. 使得javascript中的函数调用方式更像它的前生scheme, 当函数名本身是个变量的时候, 这种调用方法特别方便.
scheme里面调用函数是这样:

( apply + ‘(1,2) )

var call = Function.prototype.call.uncurrying();
var fn = function( id ) { 
    console.log( this.getElementbyId( id ) );
}

call( fn, document, "id1");

再看看jquery库,由于jquery对象( 即通过$()创建的对象 )是一个对象冒充的伪数组,它有length属性,并且能够通过下标查找对应的元素,当需要给jquery对象添加一个成员时, 伪代码大概是:

$.prototype.push = function( obj ){
this[ this.length ] = obj;
this.length = this.length + 1 // 我懂了,之前的.length 是怎么来的
}

如果用uncurrying的话, 就可以:

var push = Array.prototype.push.uncurrying();
$.prototype.push = function( obj ) {
     push( this, obj );
}

借用了array对象的push函数, 让引擎去自动管理数组成员和length属性.

而且可以一次把需要的函数全部借过来, 一劳永逸. 一段测试代码:

技术分享

反柯里化 - uncurrying

原文:http://www.cnblogs.com/abapscript/p/4878349.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!