<强>反柯里化强>
相反,反柯里化的作用在与扩大函数的适用性,使本来作为特定对象所拥有的功能的函数可以被任意对象所用。
即把如下给定的函数签名,
obj。func (__arg1、最长)
转化成一个函数形式,签名如下:
func (obj, __arg1最长)
这就是反柯里化的形式化描述。
例如,下面的一个简单实现:
Function.prototype。uncurrying=function () { var=这个; 返回函数(){ Function.prototype.call返回。应用(参数); } }; 函数sayHi () { 返回“Hello”+。值+ " " + [].slice.call(参数); } var sayHiuncurrying=sayHi.uncurrying (); console.log (sayHiuncurrying({值:‘世界’},“哈哈哈”)); >之前解释:
-
<李> uncurrying是定义在函数的原型上的方法,因此对所有的函数都可以使用此方法。调用时候:sayHiuncurrying=sayHi.uncurrying(),所以uncurrying中这个指的向的是sayHi函数;(一般原型方法中的这个不是指向原型对象原型,而是指向调用对象,在这里调用对象是另一个函数,在javascript中函数也是对象)李>
<李>调用。应用(参数),把这个设置为调用方法的上下文,然后将参数传给调用方法,前文的例子,这实际指向sayHi,所以调用sayHiuncurrying (__arg1,最长,…)相当于sayHi。调用(__arg1、最长,…);李>
<李> sayHi。调用(__arg1、最长,…),叫函数把__arg1当做sayHi的上下文,然后把最长,…等剩下的参数传给sayHi,因此最后相当于arg1.sayHi(最长,…);李>
<李>因此,这相当于sayHiuncurrying (obj, args)等于obj.sayHi (args)。李>
最后,我们反过来看,其实反柯里化相当于把原来sayHi (args)的形式,转换成了sayHiuncurrying (obj, args),使得sayHi的使用范围泛化了。更抽象地表达,uncurryinging反柯里化,使得原来x.y (z)调用,可以转成y (x, z)形式的调用。假设x '为x或者其他对象,这就扩大了函数的使用范围。
<强>通用反柯里化函数强>
上面例子中把uncurrying写进了原型,这不太好,我们其实可以把uncurrying单独封装成一个函数;
var uncurrying=函数(fn) { 返回函数(){ var args=[] .slice.call(参数,1); 返回fn.apply(参数[0],args); }};
上面这个函数很清晰直接。
使用时调用uncurrying并传入一个现有函数fn,反柯里化函数会返回一个新函数,该新函数接受的第一个实参将绑定为fn中这样的上下文,其他参数将传递给fn作为参数。
所以,对反柯里化更通俗的解释可以是函数的借用,是函数能够接受处理其他对象,通过借用泛化,扩大了函数的使用范围。
所以uncurrying更常见的用法是对Javascript内置的其他方法的借调而不用自己都去实现一遍。
文字描述比较绕,还是继续看代码:
var测试=癮, b, c”; console.log (test.split (", ")); var=uncurrying分裂(String.prototype.split);//(a, b, c的) console.log(分裂(测试','));//(a, b, c的) >之前=uncurrying分裂(String.prototype.split)给uncurrying传入一个具体的fn,即String.prototype。分裂,分裂函数就具有了String.prototype。分裂的功能,函数调用分裂(测试”、“)时,传入的第一个参数为分裂执行的上下文,剩下的参数相当于传给原String.prototype。分裂函数。
再看一个例子:
美元var={}; console.log ($ .push);//定义 var pushUncurrying=uncurrying (Array.prototype.push); 美元。推动=函数(obj) { pushUncurrying (obj); }; 美元.push('第一次'); console.log ($ . length);//1 console.log ($ [0]);//第一个 console.log ($ .hasOwnProperty(长度));//正确的 >之前这里模仿了一个“类似jquery库”实现时借用数组的推动方法。我们知道对象是没有推动方法的,所以console.log (obj.push)返回未定义,可以借用数组来处理,由原生的数组方法(js引擎)来维护伪数组对象的长度属性和数组成员。
同样的道理,我们还可以继续有:
var indexof=uncurrying (Array.prototype.indexOf); 美元。indexOf=函数(obj) { 返回indexof (obj); }; .push美元(“第二”); console.log ($ .indexOf('第一次'));//0 console.log ($ .indexOf('第二'));//1 console.log ($ .indexOf('第三'));//1浅谈JS中的反柯里化(uncurrying)