高阶函数的条件
- 函数可以作为参数被传递
- 函数可以作为返回值输出
作为参数
说明:javascript里作为参数一般都是作为回调函数,比如ajax成功之后回调函数,再比如说数据排序sort(fn),forEach等等
作为返回值
柯里化
定义:把接受多个参数的函数变成接受一个单一参数的函数,并且返回接受余下参数且返回结果的新函数。。。balabala不懂
意义:意义何在?找了很久的资料也不知道怎么用,目前的理解:就是如果一个函数有很多的参数,那就想办法把他弄在一个参数,这样必定会用到闭包,如果要用到链式,那么肯定要返回一个新的函数
//来个在strackoverflow上看到的最简单的例子
function add(a,b) {
return a+b;
}
add(3,4); //7
//用柯里化之后的函数
function sum(a) {
return function(b){
return a+b;
}
}
//此时调用该方法应该
sum(3)(4); //7
//那现在想下如果add方法需要5个参数,难道sum要嵌套5次
function currya(f) {
if(f.length==0) return f;
var _args = [];
var tempFn = function(){
[].push.apply(_args,arguments);
//f.length原来function有length这个属性,表明实参的个数
if(_args.length >= f.length) {
return f.apply(null,_args);
}else {
return tempFn; //这里返回原函数可以用argument.callee,不必关心函数名称
}
}
return tempFn;
}
function sumArgs5(a,b,c,d,e) {
return a+b+c+d+e;
}
var currySumArgs5 = currya(sumArgs5);
var b = currySumArgs5(1)(2)(3)(4)(5);
console.log(b); //15
//下面还有一种方案,有点绕.不知道这么写有什么好处,性能在哪里得到提升。
function curry(f) {
if (f.length == 0) return f;
//可能少了args的定义
function iterate(args) {
if (args.length >= f.length)
return f.apply(null, args);
return function () {
return iterate(args.concat(Array.prototype.slice.call(arguments)));
}
}
return iterate([]);
}
function mean3(a, b, c) {
return (a + b + c) / 3;
}
var curriedMean3 = curry(mean3);
console.log(curriedMean3(1)(2, 3));
console.log(curriedMean3(1)(2)(3));
console.log(curriedMean3()(1)()(2)()(3));
console.log(curriedMean3(1, 2)(3, 4));
//上面都是结果都是2,最后传入的4其实没什么用,因为方法只用到了前三个参数
//下面这种情况适合函数参数无限,只能在没有参数的时候调用被柯里化的函数
function curring(fn){
var args = [];
return function(){
if(arguments.length>0){
[].push.apply(args,arguments)
return arguments.callee; //返回当前匿名函数,可以链式的写如fn(200)(300,400)
}else{
return fn.apply(this,args);
}
}
}
var cost = curring(function(){
var args = [].slice.call(arguments);
var sum=0;
for(var i=0,len=args.length;i<len;i++){
sum+=args[i];
}
return sum;
})
cost(100)(200,400);
var a = cost();
console.log(a);
总结:根据上面三个例子,柯里化好处:
- 使用起来方便
- 参数的复用
浙公网安备 33010602011771号