推荐答案
// www.javascriptcn.com code example
function myReduce(arr, callback, initialValue) {
if (!Array.isArray(arr)) {
throw new TypeError('第一个参数必须是数组');
}
if (typeof callback !== 'function') {
throw new TypeError('第二个参数必须是函数');
}
let accumulator = initialValue;
let startIndex = 0;
if (initialValue === undefined) {
if(arr.length === 0) {
throw new TypeError('Reduce of empty array with no initial value');
}
accumulator = arr[0];
startIndex = 1;
}
for (let i = startIndex; i < arr.length; i++) {
accumulator = callback(accumulator, arr[i], i, arr);
}
return accumulator;
}
// 示例用法
const numbers = [1, 2, 3, 4, 5];
// 求和
const sum = myReduce(numbers, (acc, current) => acc + current, 0);
console.log(sum); // 输出 15
// 查找最大值
const max = myReduce(numbers, (acc, current) => Math.max(acc, current), -Infinity);
console.log(max); // 输出 5
// 不提供初始值的情况
const product = myReduce(numbers, (acc, cur) => acc * cur);
console.log(product); // 输出 120
// 错误处理
try {
myReduce(123, () => {});
} catch (error) {
console.error(error.message); // 输出:第一个参数必须是数组
}
try {
myReduce([], undefined);
} catch (error) {
console.error(error.message); // 输出:第二个参数必须是函数
}
try {
myReduce([],(acc, cur) => acc + cur);
} catch (error) {
console.error(error.message); // 输出:Reduce of empty array with no initial value
}本题详细解读
reduce 方法的作用
reduce() 方法对数组中的每个元素执行一个由您提供的 reducer 函数(升序执行),将其结果汇总为单个返回值。reduce 方法的本质在于迭代数组并处理每一个元素,最终将所有结果聚合成一个单一的值。
实现思路
- 参数校验:
- 检查第一个参数
arr是否为数组,不是则抛出TypeError。 - 检查第二个参数
callback是否为函数,不是则抛出TypeError。
- 检查第一个参数
- 初始化累加器 (accumulator):
- 如果提供了
initialValue,则将accumulator初始化为initialValue。 - 如果没有提供
initialValue,则:- 如果数组为空,抛出
TypeError,提示需要初始值。 - 否则,将
accumulator初始化为数组的第一个元素arr[0],并将循环的起始索引startIndex设置为 1(跳过第一个元素,因为它已经被用作累加器的初始值)。
- 如果数组为空,抛出
- 如果提供了
- 迭代数组:
- 使用
for循环从startIndex遍历数组。 - 在每次迭代中,调用
callback函数,传入以下参数:accumulator: 上一次callback函数的返回值或初始值。currentValue: 当前正在处理的数组元素arr[i]。currentIndex: 当前元素的索引i。array: 原始数组arr。
- 将
callback的返回值更新为新的accumulator。
- 使用
- 返回最终结果: 循环结束后,返回最终的
accumulator值。
代码解读
- 错误处理: 针对参数类型错误和未提供初始值且数组为空的情况进行了异常处理,符合
reduce方法的规范。 - 可读性: 代码逻辑清晰,通过注释说明了每个步骤的作用,易于理解。
- 兼容性: 代码使用了
for循环,兼容性较好。 - 与原生
reduce方法的对比: 实现的myReduce方法与原生reduce方法的功能和行为基本一致,包括:- 处理有初始值和无初始值的情况
- 回调函数的参数
- 异常处理
- 返回值
- 示例用法: 提供了多种示例,展示了
myReduce函数的不同使用场景,包括求和、查找最大值和不提供初始值的情况。同时,也提供了错误用法的示例,验证了错误处理机制的正确性。