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

相关推荐
EricWang135813 分钟前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
September_ning13 分钟前
React.lazy() 懒加载
前端·react.js·前端框架
时差95317 分钟前
【面试题】Hive 查询:如何查找用户连续三天登录的记录
大数据·数据库·hive·sql·面试·database
web行路人23 分钟前
React中类组件和函数组件的理解和区别
前端·javascript·react.js·前端框架
番茄小酱00124 分钟前
Expo|ReactNative 中实现扫描二维码功能
javascript·react native·react.js
子非鱼92142 分钟前
【Ajax】跨域
javascript·ajax·cors·jsonp
超雄代码狂1 小时前
ajax关于axios库的运用小案例
前端·javascript·ajax
长弓三石1 小时前
鸿蒙网络编程系列44-仓颉版HttpRequest上传文件示例
前端·网络·华为·harmonyos·鸿蒙
小马哥编程1 小时前
【前端基础】CSS基础
前端·css
嚣张农民1 小时前
推荐3个实用的760°全景框架
前端·vue.js·程序员