高阶函数英文叫Higher-order function。那么什么是高阶函数?
在数学和计算机科学中,高阶函数是至少满足下列一个条件的函数:
- 接受一个或多个函数作为输入
- 输出一个函数
高阶函数之把函数当做参数
JavaScript的函数其实都指向某个变量。既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
一个最简单的高阶函数:
function sum (x, y, f){
return f(x) + f(y)
}
当我们调用sum(-2,6, Math.abs)时,参数x,y和f分别接收-2,6和函数Math.abs(求绝对值),根据函数定义,我们可以推导计算过程为:
x = -2;y =6;f = Math.abs;f(x) + f(y) ==> Math.abs(-2) + Math.abs(6) ==>2+6 ;return 8
用代码验证一下:
sum(-2,6,Math.abs);//8
再举一个大家都熟悉的例子,Array.prototype.sort方法,接受一个函数当作参数,函数里面封装的是对数组进行排序的规则。
var arr = [1, 3, 5, 7, 2, 4, 6];
arr.sort(function(a, b) {
return a - b; //从小到大排序,如需从大到小排序,只需return b - a;
});
编写高阶函数,就是让函数的参数能够接收别的函数。还有常见的事件绑定回调函数,ajax回调函数等都属于高阶函数。
高阶函数之返回值输出
在JavaScript中,函数是第一类对象,其既可以作为参数传递,也可以作为其他函数的返回值输出。
高阶函数还可作为一种模式的构造器,比如有若干排序算法(快排,冒泡,希尔等),就可以生成一个排序器。
//排序器
var sortGenerator = function(sortFunc){
return function(args){
var arguments = [].slice.call(args);
return sortFunc(arguments);
}};
//引入快速排序算法
var quickSort = require('quickSort.js');
var quickSorter = sortingGenerator(quickSort);
//应用算法
quickSorter (4, 22, 44, 66, 77);
也许你会有疑惑我直接应用require进来的 quickSort() 就不行了。干嘛多此一举?多包装一层就可以干更多额外的事。比如测试每个排序算法的耗时。
再举个ajax封装的列子,我们写好了一个简单ajax请求服务器数据的功能,接受两个参数method和callback。请求类型和回调。每次都传入请求类型很麻烦。那么我们生成两个新的函数一个ajaxGet一个ajaxPost。
var ajaxGenerator=function(method){
return function( callback ){
ajax( method, '/url', callback )
}
}
var ajaxGet=ajaxGenerator('get')
ajaxGet(mycallback )
var ajaxPost=ajaxGenerator('post')
ajaxPost(mycallback )
以上像不像函数的柯里化,是的它属于高阶函数的降阶。
偏函数
什么是偏函数
假设有一个参数或变量已经预置的函数A,我们通过调用A来产生一个新的函数B,函数B就是我们说的偏函数。下面可以看一个示例。
// 判断类型的小demo
var isType = function(type){
return function(obj){
return toString.call(obj)=='[object '+type+']';
}
};
// 定制新的函数
var isString = isType('String');
var isArray = isType('Array');
var isFunction = isType('Function');
// 测试偏函数
console.log(isString('abc')); // true
console.log(isArray([1, 2])); // true
console.log(isFunction('abc')); // false
isType函数中预置了判断类型的方法,只指定部分参数来产生的新的定制的函数isString、isArray和isFunction就是偏函数。
其实jquery的ajax, $.get和$.post等 也是类似原理