reduce实现map、forEach、filter方法

本博客 hjy-xh,转载请申明出处

reduce如何工作

reduce()方法对于数组中的每个元素执行一个用户提供的reducer函数(升序执行),将其结果汇总为单个返回值,语法如下:

1
arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])

reducer 函数接收4个参数:

  • Accumulator (acc) (累计器)
  • Current Value (cur) (当前值)
  • Current Index (idx) (当前索引)
  • Source Array (src) (源数组)

看个简单的例子:

1
2
3
4
5
6
7
8
9
10
const source = [1, 2, 3];

// 0 + 1 + 2 + 3
const initialValue = 0;
const sum = source.reduce(
(previousValue, currentValue) => previousValue + currentValue,
initialValue
);

console.log(sum); // 6

可以看到,reduce()方法就是对传入的数组累计执行回调函数,并返回最终计算结果

实现map

map()的定义:创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值

1
2
3
4
5
6
7
8
9
10
11
Array.prototype._map = function (fn, callbackThis) {
// 最终返回的新数组
const result = [];
// 重新定义this
let cbThis = callbackThis || null;
this.reduce((before, after, index, array) => {
result.push(fn.call(cbThis, array[index], index, array))
}, null)

return result;
}
1
2
3
4
// 验证
const arr = [1, 2, 3];
const res = arr._map((current) => current * 2);
console.log(res); // [2, 4, 6]

实现forEach

forEach()的定义:对数组的每个元素执行一次给定的函数

1
2
3
4
5
6
7
Array.prototype._forEach = function (fn, callbackThis) {
// 重新定义this
let cbThis = callbackThis || null;
this.reduce((before, after, index, array) => {
fn.call(cbThis, array[index], index, array);
}, null)
}
1
2
3
4
5
6
7
// 验证
const arr = [1, 2, 3];
const res = arr._forEach((current) => console.log(current * 2));
console.log(res);
// 2
// 4
// 6

实现filter

filter()的定义:创建一个新数组, 其包含通过所提供函数实现的测试的所有元素

1
2
3
4
5
6
7
8
9
Array.prototype._filter = function (fn, callbackThis) {
const result = [];
// 重新定义this
let cbThis = callbackThis || null;
this.reduce((before, after, index, array) => {
fn.call(cbThis, array[index], index, array) ? result.push(array[index]) : null;
}, null)
return result;
}
1
2
3
4
// 验证
const arr = [1, 2, 3];
const res = arr._filter((current) => current === 2);
console.log(res); // [ 2 ]

参考

MDN