这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战
theme: juejin
问题
手写实现一个array.reduce();
需要实现的目标: 在原型链上实现reduce, 可直接被调用,例如array.myReduce();
了解array.reduce()
接收两个参数,一个处理数据的函数,一个为初始值。
接收的处理数据的函数,可接收四个参数(total,curValue,curIndex,array);
- total (上一次调用回调返回的值,或者是提供的初始值(initialValue))
- curValue (数组中当前被处理的元素)
- curIndex (当前元素在数组中的索引)
- array (调用 reduce 的数组)
手动实现
定义一个函数 myfunction(callback,initialValue);
当this或者callback 不为正确语法时,抛出错误; this指向调用reduce的数组
把调用的值通过Object(this)包装成一个类对象。如同以下,this指向1212也可以被执行,因为Object(1212) 转变成了Number {1212}
Array.prototype.reduce.call(1212,(pre,cur)=>{return ''+pre+cur},0)
0
把手写的myyReduce 写入到Array 的原型链上 Array.prototype.MyReduce = MyReduce;
function MyReduce(fun, initValue) {
if (this === null) {
// this 不存在,抛出错误
throw new TypeError( 'Array.prototype.reduce ' +
'called on null or undefined' );
}
if (typeof fun !== 'function') {
// fun 不是function时,抛出错误
throw new TypeError( fun +
' is not a function');
}
const value = Object(this);
let preValue, curValue, curIndex;
if (initValue !== undefined) {
preValue = initValue;
curValue = arr[0];
curIndex = 0;
} else {
preValue = arr[0];
curValue = arr[1];
curIndex = 1
}
for (let i = curIndex; i < value.length; i++) {
const item = value[i];
preValue = fun(preValue, item, i, arr);
}
return preValue;
}
function setReduce(preValue, curValue, index, arr) {
return `${preValue} - ${curValue}`;
}
// 把方法写入到原型链上
Array.prototype.MyReduce = MyReduce;
测试
通过定义一个数组,直接调用测试
const arr1=[1, 2, 3, 4, 5]
let num = arr1.MyReduce(setReduce);
console.log(num); // 15
总结:
reduce() 是数组的归并方法,与forEach()、map()、filter()等迭代方法一样都会对数组每一项进行遍历。
reduce() 可同时将前面数组项遍历产生的结果与当前遍历项进行运算,这一点是其他迭代方法无法企及的。
reduce() 可以作为一个高阶函数,用于函数的 compose。如何手动实现一个compose,可以通过聊聊redux里compose函数来了解。