每日前端手写题--day6

以下题目来自掘金等其它博客,但是问题的答案都是根据笔者自己的理解做出的。如果你最近想要换工作或者巩固一下自己的前端知识基础,不妨和我一起参与到每日刷题的过程中来,如何?

第六天要刷的手写题如下:

  1. 实现Array.prototype.map
  2. 实现Array.prototype.reduce
  3. 实现Array.prototype.reduceRight
  4. 实现Array.prototype.filter

下面是我自己写的答案:

1. 实现Array.prototype.map

首先必须要明白map函数的执行原理:

  • 遍历原始数组:对于调用 map() 方法的数组,会遍历每个元素。
  • 对每个元素应用回调函数:对于每个元素,都会调用传递给 map() 方法的回调函数,并传入三个参数:当前元素的值、当前元素的索引和原始数组本身。回调函数用来对每个元素进行处理。
  • 构建新数组:将回调函数返回的结果存储在新的数组中。这些结果按照原始数组的顺序排列,构成了新数组。
  • 返回新数组:当遍历完所有元素并处理完成后,map() 方法返回包含处理结果的新数组。
javascript 复制代码
function myMap (cb) {
    if(!Array.isArray(this)) throw new Error('must be called by array');
    const _stack = [...this];
    const _result = [];
    while (_stack.length) {
        const _v = _stack.pop();
        const _tmp = cb(_v, _stack.length-1, _stack);
        // do some your judgement
        _result.push(_tmp);
    }
    return _result;
}

2. 实现Array.prototype.reduce

首先必须要明白reduce函数的执行原理:

  • 初始化累加器:首先,将累加器(accumulator)的初始值设置为指定的初始值(或者默认为数组的第一个元素,如果没有提供初始值)。
  • 遍历数组元素:从数组的第一个元素开始,逐个遍历每个元素。
  • 应用回调函数:对于每个元素,都会调用传递给 reduce() 方法的回调函数,并传入四个参数:累加器、当前元素的值、当前元素的索引和原始数组本身。回调函数用来根据当前元素的值和累加器的值进行计算,并返回新的累加器值。
  • 更新累加器:将回调函数返回的新累加器值,作为下一次迭代的累加器值。
  • 返回最终结果:当遍历完所有元素后,reduce() 方法返回最终的累加器值作为计算结果。
javascript 复制代码
function myReduce (cb, initialValue) {
    if(!Array.isArray(this)) throw new Error('must be called by array');
    let _acc = initialValue ?? this[0];
    const startIndex = Number(initialValue === undefined);
    for (let i = startIndex; i < this.length; i++) {
        _acc = cb(_acc, this[i], i , this);
    }
    return _acc;
}
  • !!需要注意的是cb需要四个形参,这四个参数分别表示的含义为:归并值、当前值、当前序列号、数组本组。
  • !!需要注意的是起始位置startIndex会随着initialValue的存在而改变,如果存在则从0开始,否则将第一个元素作为initialValue并且从序列号为1开始。

3. 实现Array.prototype.reduceRight

首先必须要明白reduceRight函数的执行原理:

  • 初始化累加器:首先,将累加器(accumulator)的初始值设置为指定的初始值(或者默认为数组的最后一个元素,如果没有提供初始值)。
  • 逆向遍历数组元素:从数组的最后一个元素开始,逐个逆向遍历每个元素。
  • 应用回调函数:对于每个元素,都会调用传递给 reduceRight() 方法的回调函数,并传入四个参数:累加器、当前元素的值、当前元素的索引和原始数组本身。回调函数用来根据当前元素的值和累加器的值进行计算,并返回新的累加器值。
  • 更新累加器:将回调函数返回的新累加器值,作为下一次迭代的累加器值。
  • 返回最终结果:当逆向遍历完所有元素后,reduceRight() 方法返回最终的累加器值作为计算结果。
javascript 复制代码
function myReduce (cb, initialValue) {
    if(!Array.isArray(this)) throw new Error('must be called by array');
    let _acc = initialValue ?? this.at(-1);
    const startIndex = initialValue ? this.length -1 : this.length -2;
    for (let i = startIndex; i > 0; i--) {
        _acc = cb(_acc, this[i], i , this);
    }
    return _acc;
}

!!reduceRight和reduce的区别在于:遍历数组的方向不同,啊这样的话为什么不先把数组翻转过来呢?

4. 实现Array.prototype.filter

首先必须要明白filter函数的执行原理:

  • 创建一个空数组(称为结果数组)来存储满足条件的元素。
  • 遍历原始数组中的每个元素。
  • 对于每个元素,调用传递给 filter() 方法的回调函数,并将当前元素作为参数传递给回调函数。
  • 回调函数根据设定的条件对当前元素进行评估。如果回调函数返回 true,则表示当前元素满足条件,将其添加到结果数组中。
  • 继续遍历原始数组中的下一个元素,并重复步骤 3 和 4,直到遍历完所有元素。
  • 返回结果数组,其中包含满足条件的元素。
javascript 复制代码
function myFilter (cb) {
    if(!Array.isArray(this)) throw new Error('must be called by array');
    const _stack = [...this];
    const _result = [];
    while (_stack.length) {
        const _v = _stack.pop();
        if (cb(_v, _stack.length-1, _stack) === true) {
            _result.push(_v);
        }
    }

    return _result;
}

!!注意: 需要写成:if (cb(_v, _stack.length-1, _stack) === true) 而不是if (cb(_v, _stack.length-1, _stack))

相关推荐
_丿丨丨_5 小时前
XSS(跨站脚本攻击)
前端·网络·xss
天天进步20155 小时前
前端安全指南:防御XSS与CSRF攻击
前端·安全·xss
呼啦啦呼啦啦啦啦啦啦6 小时前
利用pdfjs实现的pdf预览简单demo(包含翻页功能)
android·javascript·pdf
拾光拾趣录7 小时前
括号生成算法
前端·算法
拾光拾趣录8 小时前
requestIdleCallback:让你的网页如丝般顺滑
前端·性能优化
前端 贾公子8 小时前
vue-cli 模式下安装 uni-ui
前端·javascript·windows
浮生带你学Java8 小时前
2025Java面试题及答案整理( 2025年 7 月最新版,持续更新)
java·开发语言·数据库·面试·职场和发展
拾光拾趣录8 小时前
链表合并:双指针与递归
前端·javascript·算法
@大迁世界8 小时前
前端:优秀架构的坟墓
前端·架构
拼图2098 小时前
element-plus——图标推荐
javascript·vue.js·elementui