一個函數就可以接收另一個函數作為參數,簡言之,函數的參數能夠接收別的函數,這種函數就稱之為高階函數
常見的高階函數有: Map、Reduce、Filter、Sort
Map
map 可以對一個集合類型的所有元素做一次映射操作
實例:將數組中的所有元素求平方,數組不變
var pow = function square(x) {
return x * x;
};
var array = [1, 2, 3, 4, 5, 6, 7, 8];
var newArr = array.map(pow);
alert(newArr); // [1, 4, 9, 16, 25, 36, 49, 64]
map()
作為高階函數,事實上它把運算規則抽象了
map()
還可以接受更加復雜的函數
例如將 array 中 數字轉為字符串,只需要一行代碼
var arr = [1, 2, 3, 4, 5, 6, 7, 8,];
arr.map(String); // ["1", "2", "3", "4", "5", "6", "7", "8"]
Reduce
把數組元素組合計算為一個值
Array
的reduce()
把一個函數作用在這個Array
的[x1, x2, x3...]
上,這個函數必須接收兩個參數,reduce()
把結果繼續和序列的下一個元素做累積計算
其效果就是:
[x1, x2, x3, x4].reduce(f) = f(f(f(x1, x2), x3), x4)
利用 reduce
對 Array
求和實現
var arr = [1, 3, 5, 7, 9];
arr.reduce(function (x, y) {
return x + y;
}); // 25
利用reduce()求積:
var arr = [1, 3, 5, 7];
arr.reduce( function(x, y) {
return x * y;
}); // 105【 (((1*3)*5)*7) = 105 】
Filter
通過條件對集合中的元素進行過濾
和map()不同的是,filter()把傳入的函數依次作用于每個元素,然后根據返回值是true還是false決定保留還是丟棄該元素。
var arr = [1, 2, 4, 5, 6, 9, 10, 15];
var r = arr.filter(function (x) {
return x % 2 !== 0;
});
r; // [1, 5, 9, 15]
Sort
對集合中的元素進行排序
默認情況下,對字符串排序,是按照ASCII的大小比較的
比較的過程必須通過函數抽象出來。通常規定,對于兩個元素x和y,如果認為x < y,則返回-1,如果認為x == y,則返回0,如果認為x > y,則返回1,這樣,排序算法就不用關心具體的比較過程,而是根據比較結果直接排序。
JavaScript的Array的sort()方法就是用于排序的,但是排序結果可能讓你大吃一驚:
// 看上去正常的結果:
['Google', 'Apple', 'Microsoft'].sort(); // ['Apple', 'Google', 'Microsoft'];
// apple排在了最后:
['Google', 'apple', 'Microsoft'].sort(); // ['Google', 'Microsoft", 'apple']
// 無法理解的結果:
[10, 20, 1, 2].sort(); // [1, 10, 2, 20]
第二個排序把apple排在了最后,是因為字符串根據ASCII碼進行排序,而小寫字母a的ASCII碼在大寫字母之后。
這是因為Array的sort()方法默認把所有元素先轉換為String再排序,結果'10'排在了'2'的前面,因為字符'1'比字符'2'的ASCII碼小。
sort()方法也是一個高階函數,它還可以接收一個比較函數來實現自定義的排序。
var arr = [10, 20, 1, 2];
var sortedArr = arr.sort(function (x, y) {
if (x < y) {
return -1;
}
if (x > y) {
return 1;
}
return 0;
});
alert(sortedArr)// [1, 2, 10, 20]
倒序
sortedArr.reverse(); // [20, 10, 2, 1]
如果要忽略字符串的大小寫進行排序,只需要對自定義高階函數小做修改就可
原理是通過把字符串都變成大寫(或者都變成小寫),再比較
var arr = ["Google", "apple", "Microsoft"];
arr.sort(function (s1, s2) {
x1 = s1.toUpperCase();
x2 = s2.toUpperCase();
if (x1 < x2) {
return -1;
}
if (x1 > x2) {
return 1;
}
return 0;
}); // ["apple", "Google", "Microsoft"]