高阶函数的条件

  1. 函数可以作为参数被传递
  2. 函数可以作为返回值输出

作为参数

说明: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);

总结:根据上面三个例子,柯里化好处:

  1. 使用起来方便
  2. 参数的复用
posted on 2016-05-20 15:59  萝卜正好  阅读(196)  评论(0)    收藏  举报