高阶函数
1.高阶函数是至少满足下列一个条件的函数:
-
接受一个或多个函数作为输入
-
输出一个函数
比如,数组自带的map、filter和reduce就是高阶函数,因为它们接受一个函数作为参数
const array1 = [1, 4, 9, 16];
const map1 = array1.map(x => x * 2);
console.log(map1); // [2, 8, 18, 32]
2.map、filter和reduce的实现过程却非常简单。需要注意下面三个问题:
-
这三个方法在哪里创建?
- 答:在Array.prototype上创建,这样才可以在实例上调用这几个方法
-
怎么在这三个方法中找到arr并循环?
- 答:this
-
我实现的函数是map、filter和reduce的完全体么?
- 答:想的很周到!真正的函数不仅仅接受一个参数,可以接受function callback(currentValue, index, array)作为参数
3.代码
3.1 手写map
/*
map映射数组(遍历数组),有return 返回一个新数组
callback的参数:
value --当前索引的值
index --索引
array --原数组
*/
let arr = [10, 20, 30, 40, 50]
Array.prototype.myMap = function (callback) {
/*
function xx (item,index){
return item * 2
}
*/
let tasks = []; // 返回新数组
for (let i = 0; i < this.length; i++) { // for循环数组的每一项 模拟循环功能
let item = callback(this[i], i, this) // 执行这个函数 传递实参
tasks.push(item) // 将item推进数数组中
}
return tasks
}
// 谁调用我 我指向谁
let result = arr.myMap(function (item, index) {
return item * 2
})
console.log(result);
3.2 手写filter
/*
过滤数组,返回一个满足要求的数组
callback的参数:
value --当前索引的值
index --索引
array --原数组
*/
// 手写filter
Array.prototype.myFilter = function (callback) {
let task = []
for (let i = 0; i < this.length; i++) {
if (callback(this[i], i, this)) {
task.push(this[i])
}
}
return task
}
let result1 = arr.myFilter(function (value, index) {
return value > 20
})
console.log(result1);
3.2 手写reduce
/*
不提供初始值 默认从1开始遍历 pre就是数组的第0项
当第二次循环时 将第一次return的结果作为第二次循环的pre的值
第一轮:10 20 1
第二轮:30 66 2
。。。
第五轮:158 235 5
*/
/*
提供初始值 从索引0处开始遍历 pre为initValue,cur为arr[0]
第一轮:0 10 0
第二轮:10 20 1
。。。
第五轮:148 10 4
第六轮:158 235 5
*/
Array.prototype.myReduce = function (callback, init) {
if (typeof callback !== "function") {
throw new TypeError(`${callback} is not a function`);
}
let result = init || this[0]; // 是否赋有初始值 且上一次的结果
for (let i = init ? 0 : 1; i < this.length; i++) { // 没有就从1开始 有就从0开始
result = callback(result, this[i], i, arr); // 返回上一次的结果
}
return result;
};
let result3 = arr.myReduce((pre, cur, index, arrList)=>{
return pre + cur
})
console.log(result3);