JavaScript 手写代码 第六期(重写数组方法三) 用于遍历的方法

news2024/9/20 20:33:25

文章目录

  • 1. 为什么要手写代码?
  • 2. 手写代码
    • 2.1 forEach
      • 2.1.1 基本使用
      • 2.1.2 手写实现
    • 2.2 map
      • 2.2.1 基本使用
      • 2.2.2 手写实现
    • 2.3 filter
      • 2.3.1 基本使用
      • 2.3.2 手写实现
    • 2.4 every
      • 2.4.1 基本使用
      • 2.4.2 手写实现
    • 2.5 some
      • 2.5.1 基本使用
      • 2.5.2 手写实现
    • 2.6 reduce
      • 2.6.1 基本使用
      • 2.6.2 手写实现
    • 2.7 find
      • 2.7.1 基本使用
      • 2.7.2 手写实现
    • 2.8 findIndex
      • 2.8.1 基本使用
      • 2.8.2 手写代码
    • 2.9 flatmap
      • 2.9.1 基本使用
      • 2.9.2 手写实现

1. 为什么要手写代码?

我们在日常开发过程中,往往都是取出来直接用,从来不思考代码的底层实现逻辑,但当我开始研究一些底层的东西的时候,才开始理解了JavaScript每个方法和函数的底层实现思路,我认为这可以很好的提高我们的代码水平和逻辑思维。

2. 手写代码

2.1 forEach

2.1.1 基本使用

forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。

            let arr = [1, 2, 3];
            arr.forEach((item, index, arr) => {
                console.log(item, index, arr);
            });

在这里插入图片描述

2.1.2 手写实现

输出结果一致

            Array.prototype.myForEach = function (callback) {
              	if (typeof callback !== 'function') {
                    throw new Error('参数必须是一个函数');
                }
                for (let i = 0; i < this.length; i++) {
                    callback(this[i], i, this);
                }
            };
            arr.myForEach(function (item, index, arr) {
                console.log(item, index, arr);
            });

2.2 map

2.2.1 基本使用

map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
map() 方法按照原始数组元素顺序依次处理元素。

原数组不会发生改变
返回新的数组:在原数组的基础上都加1

            let arr = [1, 2, 3, 4];
            let newArr = arr.map((item, index, arr) => {
                return item + 1;
            });
            console.log(newArr); // [2, 3, 4, 5]
            console.log(arr); // 不会改变原数组 [1, 2, 3, 4]

2.2.2 手写实现

            Array.prototype.myMap = function (callback) {
              	if (typeof callback !== 'function') {
                    throw new Error('参数必须是一个函数');
                }
                // 最终要返回的数组
                let result = [];
                for (let i = 0; i < this.length; i++) {
                    result.push(callback(this[i], i, this));
                }
                return result;
            };
            let newArr = arr.myMap((item, index, arr) => {
                return item + 1;
            });
            console.log(newArr); // [2, 3, 4, 5]
            console.log(arr); // 不会改变原数组 [1, 2, 3, 4]

2.3 filter

2.3.1 基本使用

filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
filter() 不会改变原始数组。

返回数组中大于3的项

            let arr = [1, 2, 3, 4, 5];
            let newArr = arr.filter((item, index, arr) => {
                return item > 2;
            });
            console.log(newArr); // [3,4,5]
            console.log(arr); // [1,2,3,4,5]

2.3.2 手写实现

            Array.prototype.myFilter = function (callback) {
              	if (typeof callback !== 'function') {
                    throw new Error('参数必须是一个函数');
                }
                let result = [];
                for (let i = 0; i < this.length; i++) {
                    // 判断是否符合item > 2,符合则push到数组res里面返回
                    callback(this[i], i, this) && result.push(this[i]);
                }
                return result;
            };
            let newArr = arr.myFilter((item, index, arr) => {
                return item > 2;
            });
            console.log(newArr); // [3,4,5]
            console.log(arr); // [1,2,3,4,5]

2.4 every

2.4.1 基本使用

every() 方法用于检测数组所有元素是否都符合指定条件(通过函数提供)。
every() 方法使用指定函数检测数组中的所有元素
如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。
如果所有元素都满足条件,则返回 true

            let arr = [1, 2, 3, 4, 5];
            let flag = arr.every((item, index, arr) => {
                return item > 4;
            });
            console.log(flag); // true

2.4.2 手写实现

            Array.prototype.myEvery = function (callback) {
              	if (typeof callback !== 'function') {
                    throw new Error('参数必须是一个函数');
                }
                for (let i = 0; i < this.length; i++) {
                    if (!callback(this[i], i, this)) {
                        return false;
                    }
                }
                return true;
            };
            let flag = arr.every((item, index, arr) => {
                return item > 4;
            });
            console.log(flag); // false

2.5 some

2.5.1 基本使用

some() 方法用于检测数组中的元素是否满足指定条件(函数提供)。
如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。
如果没有满足条件的元素,则返回false

2.5.2 手写实现

            Array.prototype.mySome = function (callback) {
                if (typeof callback !== 'function') {
                    throw new Error('参数必须是一个函数');
                }
                for (let i = 0; i < this.length; i++) {
                    if (!callback(this[i], i, this)) {
                        return false;
                    }
                }
                return true;
            };
            let flag = arr.mySome((item, index, arr) => {
                return item > 3;
            });
            console.log(flag);

2.6 reduce

2.6.1 基本使用

reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
语法:`

array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

第一个参数total:必需。初始值, 或者计算结束后的返回值。
第二个参数currentValue:必需。当前元素
第三个参数currentIndex:可选。当前元素的索引
第四个参数arr:可选。当前元素所属的数组对象。

使用示例,实现数组元素的累加

            let arr = [1, 2, 3, 4];
            let sum = arr.reduce((tol, cur) => {
                return (tol += cur);
            }, 0);
            console.log(sum); // 10

2.6.2 手写实现

            Array.prototype.myReduce = function (callback, InitialValue) {
                if (typeof callback !== 'function') {
                    throw new Error('传入第一个参数必须是函数');
                }
                const array = this;
                // 如果没有传InitaialValue初始值时,初始值默认为数组的第一项即array[0]
                let result = InitialValue || array[0];
                for (let i = 0; i < array.length; i++) {
                    // 如果没有传第二个参数InitialValue初始值,当前数组第一项就不在进入循环
                    if (!InitialValue && i == 0) {
                        continue;
                    }
                    result = callback(result, array[i], i, this);
                }
                return result;
            };
            let result = arr.myReduce((tol, cur, index, arr) => {
                return (tol += cur);
            }, 0);
            console.log(result); // 10

2.7 find

2.7.1 基本使用

find() 方法返回满足条件的数组的第一个元素的值。

            let arr = [1, 2, 3];
            let flag = arr.find((item, index, arr) => {
                return item > 2;
            });
            console.log(flag); // 3

2.7.2 手写实现

            Array.prototype.myFind = function (callback) {
                if (typeof callback !== 'function') {
                    throw new Error('传入的参数必须是函数');
                }
                for (let i = 0; i < this.length; i++) {
                    if (callback(this[i], i, this)) {
                        return this[i];
                    }
                }
                return undefined;
            };
            let flag = arr.myFind((item, index, arr) => {
                return item > 2;
            });
            console.log(flag);

2.8 findIndex

2.8.1 基本使用

findIndex() 方法返回传入一个测试条件(函数)符合条件的数组第一个元素位置。

            let arr = [1, 2, 3, 4];
            let index1 = arr.findIndex((item, index, arr) => {
                return item == 3;
            });
            console.log(index1);

2.8.2 手写代码

            Array.prototype.myFindIndex = function (callback) {
                for (let i = 0; i < this.length; i++) {
                    if (callback(this[i], i, this)) {
                        return i;
                    }
                }
                return -1;
            };

            let index1 = arr.myFindIndex((item, index, arr) => {
                return item == 3;
            });
            console.log(index1);

2.9 flatmap

2.9.1 基本使用

flatMap() 方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 map 连着深度值为 1 的 flat 几乎相同,不改变原数组
使用map遍历时,操作完成后,如果遇到操作完的元素为数组,就进行一层的拍平
flatmap

faltmap(callback,thisArg)

第一个参数callback:可以传入 (item,i,arr) 执行
第二个参数thisArg:为执行callback时的this指向 thisArg

代码示例:

            let arr = [1, 2, 3, 4, 5];
            let arr1 = arr.flatMap((item) => [item * 2]);
            console.log(arr1); // [2, 4, 6, 8, 10]
            console.log(arr); // [1, 2, 3, 4, 5] 原数组没有发生改变
            let arr2 = arr.flatMap((item) => [[item * 2]]);
            console.log(arr2); // 只能拍平一层 [[2], [4], [6], [8], [10]];
            console.log(arr); // [1, 2, 3, 4, 5]

2.9.2 手写实现


            Array.prototype.myFlatMap = function (callback, thisArg) {
                let newArr = [];
                for (let i = 0; i < this.length; i++) {
                    let res = callback.call(thisArg, arr[i], i, arr);
                    if (Array.isArray(res)) {
                        newArr.push(...res);
                    } else {
                        newArr.push(res);
                    }
                }
                return newArr;
            };
            let arr1 = arr.flatMap((item) => [item * 2]);
            console.log(arr1); // [2, 4, 6, 8, 10]
            let arr2 = arr.myFlatMap((item) => [[item * 2]]);
            console.log(arr2); // 只能拍平一层 [[2], [4], [6], [8], [10]];
欢迎大家在讨论学习,感谢大家支持

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/698215.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

虚幻引擎(UE5)-大世界分区WorldPartition教程(二)

文章目录 前言一、OFPA怎么用二、OFPA怎么用总结 上一篇&#xff1a;虚幻引擎(UE5)-大世界分区WorldPartition教程(一) 前言 在UE4版本中中&#xff0c;Actor是保存在关卡文件中的&#xff0c;也就是说&#xff0c;如果要编辑关卡中的某些Actor&#xff0c;需要签出关卡文件进…

STM32单片机(七)ADC模拟数字转换器----第二节:ADC模数转换器练习2(AD多通道)

❤️ 专栏简介&#xff1a;本专栏记录了从零学习单片机的过程&#xff0c;其中包括51单片机和STM32单片机两部分&#xff1b;建议先学习51单片机&#xff0c;其是STM32等高级单片机的基础&#xff1b;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 &#xff1a;适用于想要…

SNMP 计算机网络管理 实验2(二) SNMP服务与常用网管命令之任务三:对同学的计算机进行网络管理 任务四:查询计算机网卡的相关信息

⬜⬜⬜ &#x1f430;&#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea;(*^▽^*)欢迎光临 &#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea;&#x1f430;⬜⬜⬜ ✏️write in front✏️ &#x1f4dd;个人主页&#xff1a;陈丹宇jmu &am…

Windows下通过FastGithub加速国内GitHub访问

有时候在国内访问GitHub会非常慢&#xff0c;有时候直接打不开&#xff0c;无法访问&#xff0c;最近了解到了FastGithub 可以解决以下几个问题: github加速神器&#xff0c;解决github打不开、用户头像无法加载、releases无法上传下载、git-clone、git-pull、git-push失败等问…

刷题第二天 数组 leetcode 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II

977.有序数组的平方 给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返回 每个数字的平方 组成的新数组&#xff0c;要求也按 非递减顺序 排序。 示例 1&#xff1a; 输入&#xff1a;nums [-4,-1,0,3,10] 输出&#xff1a;[0,1,9,16,100] 解释&#xff1a;平方后&…

Use ELK with Django Log

What is ELK? The ELK Stack is a collection of three open source products: ElasticsearchLogstashKibana When to use ELK? ELK is designed to allow us to take data from any source, in any format, and to search, analyze, visualize data in real time. At t…

Java Swing编写批量模糊替换jar包小工具

用途&#xff1a;由于jar包升级需要对之前jar包进行替换&#xff0c;而版本后缀不一致需要人工手动比对 作用&#xff1a;代码升级后&#xff0c;同一个模块jar包相同只有后缀不同&#xff0c;编写小工具进行比对进行替换名称&#xff0c;避免人工核对 技术点&#xff1a;Java …

快来看看Java在编程语言中的优势与特性吧

作者主页&#xff1a;paper jie的博客_CSDN博客-C语言,算法详解领域博主 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 其他专栏&#xff1a;《系统解析C语言》《C语言》《C语言-语法篇》 内容分享&#xff1a…

iview ui vue2.0 radio 点击选中状态后取消选中状态

<RadioGroup v-model"formData.deficiencyType"><Radio label"1" :disabled"modalTypeC?true:false" click.native"cancelSelection(1)">1</Radio><Radio label"2" :disabled"modalTypeC?tru…

基于Java校园自助洗衣系设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

MIT6.584分布式-原MIT6.824-lab1-2023年万字从0到1小白学习笔记

文章目录 前置准备一、分布式系统知识的学习1.1分布式Go语言环境安装1.2MIT6.824课程的学习1.2* 前言学习 可以看到这个任务是不会完成的&#xff0c;在我们没有开始进行编码的时候1.3课程需求1.4怎么实现、借助课程的Hints1.5首先看看其mapfunction的工作逻辑&#xff1a; 二、…

2023上半年软考系统分析师科目一整理-09

2023上半年软考系统分析师科目一整理-09 IDEF (Integration DEFinition method &#xff0c;集成定义方法)是一系列建模、分析和仿真方法的统称&#xff0c;每套方法都是通过建模来获得某种特定类型的信息。其中&#xff0c; IDEFO 可以进行&#xff08;C&#xff09;建模; IDE…

互联网大厂技术-HTTP请求-Springboot整合Feign更优雅地实现Http服务调用

目录 一、SpringBoot快速整合Feign 1.添加Pom依赖 2.启动类添加注解 3.引用Feign服务 二、为请求添加Header的3种方式 1.添加固定header 2.通过接口签名添加header 3.动态添加header 三、为请求添加超时配置 1.默认超时时间 3.超时异常 4.全局超时配置 5.为单个服…

Linux:安装jdk

一、tar压缩包形式安装jdk&#xff1a; 1、安装到/opt目录下&#xff0c;如下图所示&#xff0c;先将tar.gz压缩包移动到/opt目录下&#xff0c;然后解压出来&#xff0c;命令依次是&#xff1a; tar -zxvf jdk-8u151-linux-x64.tar.gz 2、解压缩完毕后&#xff0c;我们使用ls命…

ArrayList继承了AbstractList,已经间接实现了List接口,那么为什么ArrayList还要显式实现List接口呢

这是因为,通过显式实现接口,ArrayList可以确保: 它实际上已经完整实现了List接口所规定的所有方法。 更明确地告诉其他程序员:这个类的目的是完整实现List接口。 如果ArrayList仅仅继承AbstractList,而未显式实现List接口,那么其他程序员在阅读代码时,无法立即确定这个类是否完…

STM32单片机(三)第二节:GPIO输出练习3(蜂鸣器)

❤️ 专栏简介&#xff1a;本专栏记录了从零学习单片机的过程&#xff0c;其中包括51单片机和STM32单片机两部分&#xff1b;建议先学习51单片机&#xff0c;其是STM32等高级单片机的基础&#xff1b;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 &#xff1a;适用于想要…

VTK 三维移动旋转工具 ,移动工具 旋转工具 三维旋转工具

前言&#xff1a;本文为该系列的第一篇建立3D交互窗口&#xff0c;​ 基于VTK&QT&#xff0c;建立3D交互窗口&#xff1b; 基本信息 开发平台&#xff1a;VS&QT 版 本&#xff1a;VS2017 & QT5.15.2 & VTK9.0.3 功能&#xff1a; 选中控件 移动 旋转 …

卷积神经网络的三大特性

卷积神经网络&#xff08;CNN&#xff09;的三大特性是&#xff1a; Sparse Interaction&#xff08;稀疏交互&#xff09;&#xff1a;稀疏交互是指在卷积神经网络中&#xff0c;每个神经元仅与输入数据的局部区域进行交互。这意味着神经元只对输入数据的一小部分感知&#xf…

Qt自定义控件(数字框与拖拽条互动)

一、效果 自定义红色区域组件&#xff0c;做到数字与拖拽条相互影响。 二、实现 输入合适的名字 打开自定义组件ui 选择合适的组件进行布局 将两个空间的信号和值进行绑定 新增自定义函数并实现 #include "smallwidget.h" #include "ui_smallwidget.h"sma…

从架构角度看网络安全:数字化时代企业如何构建防御体系?

导语 | 数字化时代&#xff0c;网络安全已经成为企业发展的重中之重&#xff0c;通过体系化的安全建设&#xff0c;企业可以从容应对愈加复杂的网络安全挑战。今天&#xff0c;我们特邀了腾讯云 TVP、赛博英杰科技董事长 谭晓生老师&#xff0c;他将从资深技术专家视角解读如何…