题目
使用数组的map方法实现一个reduce的功能
数组的 reduce 方法简介
reduce(callbackFn, initialValue)
-
callbackFn 为数组中每个元素执行的函数。其返回值将作为下一次调用 callbackFn 时的 accumulator 参数。对于最后一次调用,返回值将作为 reduce() 的返回值。该函数被调用时将传入以下参数:
- accumulator 上一次调用 callbackFn 的返回的结果。在第一次调用时,如果指定了 initialValue 则为指定的值,否则为 array[0] 的值。
- currentValue 当前元素的值。在第一次调用时,如果指定了 initialValue,则为 array[0] 的值,否则为 array[1]。
- currentIndex currentValue 在数组中的索引位置。在第一次调用时,如果指定了 initialValue 则为 0,否则为 1。
- array 调用了 reduce() 的数组本身。
-
initialValue 可选 第一次调用回调时初始化 accumulator 的值。误。
返回值 使用“reducer”回调函数遍历整个数组后的结果。
数组的 map 方法简介
创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。
map(callback, thisArg)
- callbackFn 为数组中的每个元素执行的函数。它的返回值作为一个元素被添加为新数组中。该函数被调用时将传入以下参数:
- element 数组中当前正在处理的元素。
- index 正在处理的元素在数组中的索引。
- array 调用了 map() 的数组本身。
- thisArg 可选 执行 callbackFn 时用作 this 的值。参见迭代方法。
返回值 一个新数组,每个元素都是回调函数的返回值。
模拟 map 方法的上下文
由于map
方法多一个传入上下文的功能因此我们先将数组作用域和上下文存储起来
Array.prototype.myMap = function (callbackFn, thisArg) {
const arr = this // 存储数组
const ctx = thisArg || this // 存储传入的上下文作用域,如果没有传入就使用数组作用域
}
reduce 模拟
在我们的myMap
方法中,调用reduce
方法,将reduce
中的item
和index
都传入回调函数中
arr.reduce((accumulator, item, index) => {
callbackFn.call(ctx, item, index, arr)
})
这样掉完,发现少调了一个方法并且map
函数是要返回一个新的数组,而这里我们没有返回新数组,这就需要:
- 提供一个初始数组,将
callbackFn
执行完的结果塞入数组里面 - 将
reduce
执行完成后的结果返回出去
因此我们整理一下上面的代码,myMap
函数里面就变成
return arr.reduce((accumulator, item, index) => {
accumulator.push(callbackFn.call(ctx, item, index, arr))
return accumulator
}, [])
综合一下,得出最终结果
Array.prototype.myMap = function (callbackFn, thisArg) {
const arr = this
const ctx = thisArg || this
return arr.reduce((accumulator, item, index) => {
accumulator.push(callbackFn.call(ctx, item, index, arr))
return accumulator
}, [])
}
接下来我们放在浏览器里面跑一下,非常完美