高阶函数
将另一个函数作为参数或将函数定义为返回值的函数称为高阶函数。
构建高阶函数
既然知道了高阶函数的定义,那我们就可以构建高阶函数了
1. 将函数作为参数
这种将函数作为参数的方法通常被用在回调函数中。 回调函数是在所有其他操作完成后在操作结束时执行的函数。如果将函数作为参数传入父元素中,并在父函数的其他操作都完成后再运行,这样可以处理回调函数的异步行为。
我们经常使用的js事件监听用的就是这种思想。
const ele = document.getElementById('test');
ele.addEventListener('animationstart', this.listener, false);
listener(e) {
const ele = document.createElement('li');
switch (e.type) {
case 'animationstart':
ele.innerHTML = 'Started: elapsed time is' + e.elapsedTime;
break;
case 'animationend':
ele.innerHTML = 'Ended: elapsed time is' + e.elapsedTime;
break;
case 'animationiteration':
ele.innerHTML = 'New loop started at time' + e.elapsedTime;
break;
default:
break;
}
document.getElementById('output').appendChild(ele);
}
当然也可以将函数体的内容以匿名函数写在参数里面。
const ele = document.getElementById('test');
ele.addEventListener('animationstart', function(e) {
const ele = document.createElement('li');
switch (e.type) {
case 'animationstart':
ele.innerHTML = 'Started: elapsed time is' + e.elapsedTime;
break;
case 'animationend':
ele.innerHTML = 'Ended: elapsed time is' + e.elapsedTime;
break;
case 'animationiteration':
ele.innerHTML = 'New loop started at time' + e.elapsedTime;
break;
default:
break;
}
document.getElementById('output').appendChild(ele);
}, false);
2. 将函数定义为返回值
将函数定义为返回值在函数科里化中用的比较多。
testAttitude(original, replacement, source) {
return function(source) {
return source.replace(original, replacement);
}
}
const goodMan = this.testAttitude(/好人/ig, '坏人');
const badMan = this.testAttitude(/坏人/ig, '好人');
console.log(goodMan('我是一个好人,偶像,你挑的嘛')); // 我是一个坏人,偶像,你挑的嘛
console.log(badMan('我是一个坏人,偶像,你挑的嘛')); // 我是一个好人,偶像,你挑的嘛
常见的高阶函数及其应用
在实际开发中,我们常用的封装好的的高阶函数有很多。按照上面我们对高阶函数的定义,可以将高阶函数分为两类
函数作为参数
filter()
- 需要传入一个回调函数
- 回调函数有两个参数item,index
- 不会改变原来的数组
- 如果找不到满足条件的数组,则返回undefined
- 不会对空数组进行校验
- 回调函数需要返回值
应用
过滤数组,返回满足条件的数组。
const arr = [0, 1, 3, 5, 7, 9];
const result = arr.filter((item, index) => {
console.log(item, index);
return item < 5;
})
console.log(arr); // [0, 1, 3, 5, 7, 9]
console.log('返回结果', result); // [0, 1, 3]
map()
- 需要传入一个回调函数
- 回调函数有两个参数item,index
- 不会改变原来的数组
- 不会对空数组进行校验
- 回调函数需要返回值
应用
对数组中的每一项进行相同的处理。
const arr = [0, 1, 3, 5, 7, 9];
const result = arr.map((item, index) => {
console.log(item, index);
return item * 2;
})
console.log(arr); // [0, 1, 3, 5, 7, 9]
console.log('返回结果', result); // [0, 2, 6, 10, 14, 18]
foreach()
- 需要传入一个回调函数
- 回调函数有两个参数item,index
- 回调函数不需要返回值,因此总是返回undefined
- 不会改变原来的数组
- 空数组不会执行回调函数
应用
遍历数组,对数组进行处理
const arr = [0, 1, 3, 5, 7, 9];
const result = arr.forEach((item, index) => {
console.log(item, index);
item = 5;
})
console.log(arr); // [0, 1, 3, 5, 7, 9]
console.log('返回结果', result); // undefined
sort()
- 需要传入一个回调函数
- 回调函数有两个参数a(当前值),b(下一个值)
- 会改变原来的数组
应用
对数组进行排序,升序或者降序
const arr = [0, 1, 2, 4, 6, 8, 3, 5, 7, 9];
const result = arr.sort((a, b) => {
console.log(a, b);
return a - b;
})
console.log(arr); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log('返回结果', result); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
findIndex()
- 需要传入一个回调函数
- 回调函数有两个参数item,index
- 不会改变原来的数组
- 如果找不到满足条件的元素,则返回-1
应用
找到数组中满足条件的第一个元素的索引值index
const arr = [0, 1, 2, 4, 6, 8, 3, 5, 8, 9];
const result = arr.findIndex((item, index) => {
console.log(item, index);
return item === 8;
})
console.log(arr); // [0, 1, 2, 4, 6, 8, 3, 5, 7, 9]
console.log('返回结果', result); // 5
some()
- 需要传入一个回调函数
- 回调函数有两个参数item,index
- 不会改变原来的数组
- 如果找不到满足条件的数组,则返回false
- 不会对空数组进行校验
应用
判断当前数组中是否存在某元素,存在则返回true, 否则则返回false
const arr = [0, 1, 2, 4, 6, 8, 3, 5, 8, 9];
const result = arr.some((item, index) => {
console.log(item, index);
return item === 8;
})
console.log(arr); // [0, 1, 2, 4, 6, 8, 3, 5, 8, 9]
console.log('返回结果', result); // false
every()
- 需要传入一个回调函数
- 回调函数有两个参数item,index
- 不会改变原来的数组
- 如果找不到满足条件的数组,则返回false
- 只要有一项不满足条件,就不会继续往下执行了
- 不会对空数组进行校验
应用
判断数组中的每一项是否都满足条件,满足返回true,只要有一项不满足就是false.
onst arr = [0, 1, 2, 4, 6, 8, 3, 5, 8, 9];
const result = arr.every((item, index) => {
console.log(item, index);
return item >= 0;
})
console.log(arr); // [0, 1, 2, 4, 6, 8, 3, 5, 8, 9]
console.log('返回结果', result); // true
find()
- 需要传入一个回调函数
- 回调函数有两个参数item,index
- 不会改变原来的数组
- 如果找不到满足条件的数组,则返回undefined
- 如果找到满足条件的值就不会继续往下找了
- 不会对空数组进行校验
应用
找到数组中满足条件的元素,和some, findIndex类似,只是find返回的是元素本身,some返回的是布尔值,findIndex返回的是元素的索引index
const arr = [0, 1, 2, 4, 6, 8, 3, 5, 8, 9];
const result = arr.find((item, index) => {
console.log(item, index);
return item > 0;
})
console.log(arr); // [0, 1, 2, 4, 6, 8, 3, 5, 8, 9]
console.log('返回结果', result); // 1
reduce()
- 需要传入一个回调函数
- 回调函数有四个参数pre(必须),current(必须),currentIndex(可选),arr(可选)
- 不会改变原来的数组
应用
适用于对数组中的元素从左往右进行累计计算。
const arr = [0, 1, 2, 4, 6, 8, 3, 5, 8, 9];
const result = arr.reduce((preVal, curVal) => {
return preVal + curVal;
})
console.log(arr); // [0, 1, 2, 4, 6, 8, 3, 5, 8, 9]
console.log('返回结果', result); // 46
reduceRight()
- 需要传入一个回调函数
- 回调函数有四个参数pre(必须),current(必须),currentIndex(可选),arr(可选)
- 不会改变原来的数组
应用
适用于对数组中的元素从右往左进行累计计算。
const arr = [0, 1, 2, 4, 6, 8, 3, 5, 8, 9];
const result = arr.reduceRight((preVal, curVal) => {
return preVal + curVal;
})
console.log(arr); // [0, 1, 2, 4, 6, 8, 3, 5, 8, 9]
console.log('返回结果', result); // 46