高階函數(shù)
在 JavaScript 中辟宗,函數(shù)是一種特殊類型的對(duì)象僵朗,它們是 Function objects。高階函數(shù)英文叫 Higher-order function即寡,它的定義很簡(jiǎn)單修然,就是至少滿足下列一個(gè)條件的函數(shù):
接受一個(gè)或多個(gè)函數(shù)作為輸入
輸出一個(gè)函數(shù)
也就是說高階函數(shù)是對(duì)其他函數(shù)進(jìn)行操作的函數(shù)笛钝,可以將它們作為參數(shù)傳遞,或者是返回它們愕宋。 簡(jiǎn)單來說玻靡,高階函數(shù)是一個(gè)接收函數(shù)作為參數(shù)傳遞或者將函數(shù)作為返回值輸出的函數(shù)。
函數(shù)作為參數(shù)傳遞
JavaScript 語言中內(nèi)置了一些高階函數(shù)中贝,比如 Array.prototype.map囤捻,Array.prototype.filter 和 Array.prototype.reduce,它們接受一個(gè)函數(shù)作為參數(shù)邻寿,并應(yīng)用這個(gè)函數(shù)到列表的每一個(gè)元素蝎土。我們來看看使用它們與不使用高階函數(shù)的方案對(duì)比视哑。
Array.prototype.map
map() 方法創(chuàng)建一個(gè)新數(shù)組,其結(jié)果是該數(shù)組中的每個(gè)元素都調(diào)用一個(gè)提供的函數(shù)后返回的結(jié)果誊涯,原始數(shù)組不會(huì)改變黎炉。傳遞給 map 的回調(diào)函數(shù)(callback)接受三個(gè)參數(shù),分別是 currentValue醋拧、index(可選)、array(可選)淀弹,除了 callback 之外還可以接受 this 值(可選)丹壕,用于執(zhí)行 callback 函數(shù)時(shí)使用的this 值。
來個(gè)簡(jiǎn)單的例子方便理解薇溃,現(xiàn)在有一個(gè)數(shù)組 [1, 2, 3, 4]菌赖,我們想要生成一個(gè)新數(shù)組,其每個(gè)元素皆是之前數(shù)組的兩倍沐序,那么我們有下面兩種使用高階和不使用高階函數(shù)的方式來實(shí)現(xiàn)琉用。
不使用高階函數(shù)
const arr1 = [1, 2, 3, 4];
const arr2 = [];
for (let i = 0; i < arr1.length; i++) {
arr2.push( arr1[i] * 2);
}
console.log( arr2 );
// [2, 4, 6, 8]
console.log( arr1 );
// [1, 2, 3, 4]
使用高階函數(shù)
const arr1 = [1, 2, 3, 4];
const arr2 = arr1.map(item => item * 2);
console.log( arr2 );
// [2, 4, 6, 8]
console.log( arr1 );
// [1, 2, 3, 4]
Array.prototype.filter
filter() 方法創(chuàng)建一個(gè)新數(shù)組, 其包含通過提供函數(shù)實(shí)現(xiàn)的測(cè)試的所有元素,原始數(shù)組不會(huì)改變策幼。接收的參數(shù)和 map 是一樣的邑时,其返回值是一個(gè)新數(shù)組、由通過測(cè)試的所有元素組成特姐,如果沒有任何數(shù)組元素通過測(cè)試晶丘,則返回空數(shù)組。
來個(gè)例子介紹下唐含,現(xiàn)在有一個(gè)數(shù)組 [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4]浅浮,我們想要生成一個(gè)新數(shù)組,這個(gè)數(shù)組要求沒有重復(fù)的內(nèi)容捷枯,即為去重滚秩。
不使用高階函數(shù)
const arr1 = [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4];
const arr2 = [];
for (let i = 0; i < arr1.length; i++) {
if (arr1.indexOf( arr1[i] ) === i) {
arr2.push( arr1[i] );
}
}
console.log( arr2 );
// [1, 2, 3, 5, 4]
console.log( arr1 );
// [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4]
使用高階函數(shù)
const arr1 = [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4];
const arr2 = arr1.filter( (element, index, self) => {
return self.indexOf( element ) === index;
});
console.log( arr2 );
// [1, 2, 3, 5, 4]
console.log( arr1 );
// [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4]
Array.prototype.reduce
reduce() 方法對(duì)數(shù)組中的每個(gè)元素執(zhí)行一個(gè)提供的 reducer 函數(shù)(升序執(zhí)行),將其結(jié)果匯總為單個(gè)返回值淮捆。傳遞給 reduce 的回調(diào)函數(shù)(callback)接受四個(gè)參數(shù)郁油,分別是累加器 accumulator、currentValue争剿、currentIndex(可選)已艰、array(可選),除了 callback 之外還可以接受初始值 initialValue 值(可選)蚕苇。
如果沒有提供 initialValue哩掺,那么第一次調(diào)用 callback 函數(shù)時(shí),accumulator 使用原數(shù)組中的第一個(gè)元素涩笤,currentValue 即是數(shù)組中的第二個(gè)元素嚼吞。 在沒有初始值的空數(shù)組上調(diào)用 reduce 將報(bào)錯(cuò)盒件。
如果提供了 initialValue,那么將作為第一次調(diào)用 callback 函數(shù)時(shí)的第一個(gè)參數(shù)的值舱禽,即 accumulator炒刁,currentValue 使用原數(shù)組中的第一個(gè)元素。
來個(gè)簡(jiǎn)單的例子介紹下誊稚,現(xiàn)在有一個(gè)數(shù)組 [0, 1, 2, 3, 4]翔始,需要計(jì)算數(shù)組元素的和,需求比較簡(jiǎn)單里伯,來看下代碼實(shí)現(xiàn)城瞎。
不使用高階函數(shù)
const arr = [0, 1, 2, 3, 4];
let sum = 0;
for (let i = 0; i < arr.length; i++) {
sum += arr[i];
}
console.log( sum );
// 10
console.log( arr );
// [0, 1, 2, 3, 4]
使用高階函數(shù)
//無 initialValue 值
const arr = [0, 1, 2, 3, 4];
let sum = arr.reduce((accumulator, currentValue, currentIndex, array) => {
return accumulator + currentValue;
});
console.log( sum );
// 10
console.log( arr );
// [0, 1, 2, 3, 4]
//有 initialValue 值10
const arr = [0, 1, 2, 3, 4];
let sum = arr.reduce((accumulator, currentValue, currentIndex, array) => {
return accumulator + currentValue;
}, 10);
console.log( sum );
// 20
console.log( arr );
// [0, 1, 2, 3, 4]