每日前端手写题--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))

相关推荐
如若12313 分钟前
对文件内的文件名生成目录,方便查阅
java·前端·python
滚雪球~1 小时前
npm error code ETIMEDOUT
前端·npm·node.js
沙漏无语1 小时前
npm : 无法加载文件 D:\Nodejs\node_global\npm.ps1,因为在此系统上禁止运行脚本
前端·npm·node.js
supermapsupport1 小时前
iClient3D for Cesium在Vue中快速实现场景卷帘
前端·vue.js·3d·cesium·supermap
brrdg_sefg1 小时前
WEB 漏洞 - 文件包含漏洞深度解析
前端·网络·安全
胡西风_foxww1 小时前
【es6复习笔记】rest参数(7)
前端·笔记·es6·参数·rest
m0_748254881 小时前
vue+elementui实现下拉表格多选+搜索+分页+回显+全选2.0
前端·vue.js·elementui
ThisIsClark2 小时前
【后端面试总结】深入解析进程和线程的区别
java·jvm·面试
星就前端叭2 小时前
【开源】一款基于Vue3 + WebRTC + Node + SRS + FFmpeg搭建的直播间项目
前端·后端·开源·webrtc
m0_748234522 小时前
前端Vue3字体优化三部曲(webFont、font-spider、spa-font-spider-webpack-plugin)
前端·webpack·node.js