实现原生reduce方法
/**
* @template T, U
* @param {(previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U} callbackFn
* @param {U} [initialValue]
* @return {Array<U>}
*/
Array.prototype.myReduce = function (callbackFn, initialValue) {
if (typeof callbackFn !== 'function') {
throw new TypeError('callbackFn is not function');
}
const arr = this;
const len = arr.length;
let startIndex = 0;
let accumulator = initialValue;
if (arguments.length < 2) {
let found = false;
let index = 0;
while(index < len) {
if (arr.hasOwnProperty(index)) {
found = true;
startIndex = index + 1;
accumulator = arr[index];
break;
}
index++;
}
if (!found) {
throw new TypeError('empty array with no initialValue');
}
}
for (let i=startIndex;i<len;i++) {
if(arr.hasOwnProperty(i)) {
accumulator = callbackFn(accumulator, arr[i], i, arr);
}
}
return accumulator;
};
要点
- 当initialValue无值时,需要给定默认值,通常为arr[0];但arr[0]可能为empty,所以需要考虑稀疏数组的情况,且为防止arr[0]重复运算,startIndex应为1
- 需要考虑数组全为empty的情况
测试用例
const add = (acc, curr) => acc + curr
[1,2,3].myReduce(add) // 6
[,1,2,3].myReduce(add) // 6
[,,,].myReduce(add) // TypeError: empty array with no initialValue