javascriptcurrying返回函数的函数
函数 返回
2023-06-13 09:14:14 时间
最早期的curry函数有点多态的意味,就是根据函数参数在内部选用分支:
复制代码代码如下:
//http://www.openlaszlo.org/pipermail/laszlo-user/2005-March/000350.html
//★★On8Mar2005,at00:06,SteveAlbinwrote:
functionadd(a,b){
if(arguments.length<1){
returnadd;
}elseif(arguments.length<2){
returnfunction(c){returna+c}
}else{
returna+b;
}
}
varmyadd=add(2);
vartotal=myadd(3);
日本的一个先行者可能在未搞清arguments也能用Array的原生方法转换为数组的时候,用非常复杂的正则与eval搞出一个更接近现代currying意味的函数。
functioncurry(fun){
if(typeoffun!="function"){
thrownewError("Theargumentmustbeafunction.");
}
if(fun.arity==0){
thrownewError("Thefunctionmusthavemorethanoneargument.");
}
varfunText=fun.toString();
varargs=/function.*\((.*)\)(.*)/.exec(funText)[1].split(",");
varfirstArg=args.shift();
varrestArgs=args.join(",");
varbody=funText.replace(/function.*\(.*\)/,"");
varcurriedText=
"function("+firstArg+"){"+
"returnfunction("+restArgs+")"+body+
"}";
eval("varcurried="+curriedText);
returncurried;
}
接着是闭包的流行,与数组转换arguments的技术的发现,现代currying函数终于粉墨登场,就好像15~17世纪大航海时代的地理大发现,javascript的世界突然间开阔了许多。
//一个简单的现代currying函数
functioncurry(fn,scope){
varscope=scope||window;
varargs=[];
for(vari=2,len=arguments.length;i<len;++i){
args.push(arguments[i]);
};
returnfunction(){
fn.apply(scope,args);
};
}
一般的currying函数只有两重,执行情况如下,第一次执行参数不足返回内部函数,第二次执行才最终完成。不过针对这参数,我们还是可以做一些文章。看如下函数:
functionsum(){
varresult=0;
for(vari=0,n=arguments.length;i<n;i++){
result+=arguments[i];
}
returnresult;
}
alert(sum(1,2,3,4,5));//15
这就没有所谓的参数不足问题,传入一个参数,它也计算。但不传入参数呢?无错,区别在于有没有参数。我们可以让它不断执行自身,如果参数存在的情况下。最后在没有参数的情况下,一次过执行。换言之,前面的步骤是用于储存参数。
varsum2=curry(sum);
sum2=sum2(1)(2)(3)(4)(5);
sum2();//15
比起一般的currying函数,这有点难度。具体看注解:
varcurry=function(fn){//原函数的参数为函数
returnfunction(args){//内部函数的参数为数组,由于立即执行,因此直接到第三重去
//args是相对于第三重内部函数可是全局变量
varself=arguments.callee;//把自身保存起来(就是那个数组为参数的第二重函数)
returnfunction(){//这才是第二次调用的函数
if(arguments.length){//如果还有要添加的参数
[].push.apply(args,arguments);//apply把当前传入的所有参数放进args中
returnself(args);
}else{
returnfn.apply(this,args);//apply的第二参数为数组
}
}
}([]);
};
或者每次传入多个参数:
但上面的函数有不足之处,最后怎么也要放个括号,我们想只要参数足够就返回结果,多出的参数忽略。改进如下:
functioncurry(f){
if(f.length==0)returnf;
functioniterate(args){
if(args.length<=f.length)
returnf.apply(null,args);
returnfunction(){
returniterate(args.concat(Array.prototype.slice.call(arguments)));
};
}
returniterate([]);
}
相关文章
- 一次nginx返回422状态码的经历
- 【说站】JavaScript定义函数的两种方法
- php中关于strtotime函数31日取前几个月日期的BUG
- C语言函数返回 1 和返回 0 哪个好?
- 【Kotlin 协程】Flow 异步流 ① ( 以异步返回返回多个返回值 | 同步调用返回多个值的弊端 | 尝试在 sequence 中调用挂起函数返回多个返回值 | 协程中调用挂起函数返回集合 )
- JAVA调用Oracle存储过程和函数详解数据库
- 利用Oracle函数实现多值返回(oracle返回多个值)
- 函数探索MySQL中Exp()函数的威力(mysqlexp)
- 函数探究Linux下atoi函数的奥秘(linuxatoi)
- 函数深入分析Linux atoi函数(linuxatoi)
- Oracle中使用Replace函数替换字符串(oracle中替换字符串)
- MySQL:Unlocking Power with JSON Functions(mysqljson函数)
- 深入理解 Oracle 返回表函数(oracle返回表函数)
- 探索Oracle中文函数的乐趣(oracle中文函数)
- [推荐]ASP编程通用函数收藏大全
- php数组函数序列之prev()-移动数组内部指针到上一个元素的位置,并返回该元素值
- android上一个可追踪代码具体到函数某行的日志类
- c语言printf函数的使用详解
- 比较strtr,str_replace和preg_replace三个函数的效率
- 深入解析函数指针与返回函数的指针
- js函数返回多个返回值的示例代码
- python函数返回多个值的示例方法
- oracle日期时间函数使用总结
- Python过滤函数filter()使用自定义函数过滤序列实例