高階函數(shù)英文叫Higher-order function峦睡。那么什么是高階函數(shù)蔫骂?
在數(shù)學(xué)和計(jì)算機(jī)科學(xué)中,高階函數(shù)是至少滿足下列一個(gè)條件的函數(shù):
- 接受一個(gè)或多個(gè)函數(shù)作為輸入
- 輸出一個(gè)函數(shù)
高階函數(shù)之把函數(shù)當(dāng)做參數(shù)
JavaScript的函數(shù)其實(shí)都指向某個(gè)變量。既然變量可以指向函數(shù)裸卫,函數(shù)的參數(shù)能接收變量彬祖,那么一個(gè)函數(shù)就可以接收另一個(gè)函數(shù)作為參數(shù)茁瘦,這種函數(shù)就稱之為高階函數(shù)。
一個(gè)最簡單的高階函數(shù):
function sum (x, y, f){
return f(x) + f(y)
}
當(dāng)我們調(diào)用sum(-2储笑,6, Math.abs)時(shí)甜熔,參數(shù)x,y和f分別接收-2突倍,6和函數(shù)Math.abs(求絕對值)腔稀,根據(jù)函數(shù)定義盆昙,我們可以推導(dǎo)計(jì)算過程為:
x = -2;y =6;f = Math.abs;f(x) + f(y) ==> Math.abs(-2) + Math.abs(6) ==>2+6 ;return 8
用代碼驗(yàn)證一下:
sum(-2,6,Math.abs);//8
再舉一個(gè)大家都熟悉的例子,Array.prototype.sort方法焊虏,接受一個(gè)函數(shù)當(dāng)作參數(shù)淡喜,函數(shù)里面封裝的是對數(shù)組進(jìn)行排序的規(guī)則。
var arr = [1, 3, 5, 7, 2, 4, 6];
arr.sort(function(a, b) {
return a - b; //從小到大排序诵闭,如需從大到小排序炼团,只需return b - a;
});
編寫高階函數(shù),就是讓函數(shù)的參數(shù)能夠接收別的函數(shù)疏尿。還有常見的事件綁定回調(diào)函數(shù)瘟芝,ajax回調(diào)函數(shù)等都屬于高階函數(shù)。
高階函數(shù)之返回值輸出
在JavaScript中褥琐,函數(shù)是第一類對象锌俱,其既可以作為參數(shù)傳遞,也可以作為其他函數(shù)的返回值輸出敌呈。
高階函數(shù)還可作為一種模式的構(gòu)造器贸宏,比如有若干排序算法(快排,冒泡驱富,希爾等)锚赤,就可以生成一個(gè)排序器。
//排序器
var sortGenerator = function(sortFunc){
return function(args){
var arguments = [].slice.call(args);
return sortFunc(arguments);
}};
//引入快速排序算法
var quickSort = require('quickSort.js');
var quickSorter = sortingGenerator(quickSort);
//應(yīng)用算法
quickSorter (4, 22, 44, 66, 77);
也許你會有疑惑我直接應(yīng)用require進(jìn)來的 quickSort() 就不行了褐鸥。干嘛多此一舉线脚?多包裝一層就可以干更多額外的事。比如測試每個(gè)排序算法的耗時(shí)叫榕。
再舉個(gè)ajax封裝的列子浑侥,我們寫好了一個(gè)簡單ajax請求服務(wù)器數(shù)據(jù)的功能,接受兩個(gè)參數(shù)method和callback晰绎。請求類型和回調(diào)寓落。每次都傳入請求類型很麻煩。那么我們生成兩個(gè)新的函數(shù)一個(gè)ajaxGet一個(gè)ajaxPost荞下。
var ajaxGenerator=function(method){
return function( callback ){
ajax( method, '/url', callback )
}
}
var ajaxGet=ajaxGenerator('get')
ajaxGet(mycallback )
var ajaxPost=ajaxGenerator('post')
ajaxPost(mycallback )
以上像不像函數(shù)的柯里化伶选,是的它屬于高階函數(shù)的降階。
偏函數(shù)
什么是偏函數(shù)
假設(shè)有一個(gè)參數(shù)或變量已經(jīng)預(yù)置的函數(shù)A尖昏,我們通過調(diào)用A來產(chǎn)生一個(gè)新的函數(shù)B仰税,函數(shù)B就是我們說的偏函數(shù)。下面可以看一個(gè)示例抽诉。
// 判斷類型的小demo
var isType = function(type){
return function(obj){
return toString.call(obj)=='[object '+type+']';
}
};
// 定制新的函數(shù)
var isString = isType('String');
var isArray = isType('Array');
var isFunction = isType('Function');
// 測試偏函數(shù)
console.log(isString('abc')); // true
console.log(isArray([1, 2])); // true
console.log(isFunction('abc')); // false
isType函數(shù)中預(yù)置了判斷類型的方法陨簇,只指定部分參數(shù)來產(chǎn)生的新的定制的函數(shù)isString、isArray和isFunction就是偏函數(shù)迹淌。
其實(shí)jquery的ajax, $.get和$.post等 也是類似原理