首页 > 代码库 > js科里化
js科里化
科里化定义如下: 首先将一批函数转入一个函数(然后这个函数返回一个新的函数),这中形式就叫“做科里化”(currying)
Function.prototype.curry = function(){ var fn = this, // 这里就是在预装参数,将参数抓住,缓存在变量args中 args = Array.prototype.slice.call(arguments); return function(){ return fn.apply(this, args.concat( Array.prototype.slice.call(arguments))) }; }; String.prototype.csv = String.prototype.split.curry(/,\s*/); var results = ("Mugan, Jin, Fuu").csv(); console.log(results[0],results[1],results[2]);
上面这个例子看懂了吗?
curry这个函数做的事情,是将函数中的this和arguments缓存在了闭包之中。
当split函数调用curry的时候,curry中的this就是split函数本身, 正则表达式这个参数则是预存在curyry中的arguments。
虽然这段代码实现已经很不错了,但是我们还可以进行一些改进。 上面这个curry函数,实现了将所有参数缓存在闭包之中。 当调用闭包返回的新的函数的时候才去处理之前预装的所有参数。
但是如果我不想让所有的参数全部预装,而是只预装其中一部分, 另外一部分参数要在调用闭包返回的那个新的函数中,将这部分参数传入。
Function.prototype.partial = function(){ var fn = this, args = Array.prototype.slice.call(arguments); return function(){ var arg = 0; for (var i = 0; i < args.length && arg < arguments.length; i++){ if (args[i] === undefined){ args[i] = arguments[arg++]; } } return fn.apply(this, args); }; }; var delay = setTimeout.partial(undefined, 10); delay(function(){ alert(true); }); var bindClick = document.body.addEventListener.partial("click", undefined, false); bindClick(function(){ alert(true); });
partial()的实现和curry()有些相像。 在第一批的参数中,我们用undefined代表了那部分缺省参数。 在后面delay调用的时候,才将真正想要被处理的参数传递进去。
var curry = function(fn){ //参数集合 var args = []; //函数的形参个数 var fnLen = fn.length; return function(){ //合并参数 args = args.concat([].slice.call(arguments)); //返回函数自身 if(args.length < fnLen) return arguments.callee; //执行函数并返回结果 return fn.apply(this,args); }; }; var fn=function(a,b,c){ return a+b+c; }; var c = curry(fn)(1)(2)(3); alert(c); //6
js科里化
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。