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

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

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]];


目录
相关文章
|
5月前
|
监控 负载均衡 JavaScript
有哪些有效的方法可以优化Node.js应用的性能?
有哪些有效的方法可以优化Node.js应用的性能?
321 69
|
4月前
|
JavaScript Linux 内存技术
Debian 11系统下Node.js版本更新方法详解
本指南详细介绍在Linux系统中安装和管理Node.js的步骤。首先检查现有环境,包括查看当前版本和清除旧版本;接着通过NodeSource仓库安装最新版Node.js并验证安装结果。推荐使用nvm(Node Version Manager)进行多版本管理,便于切换和设置默认版本。同时,提供常见问题解决方法,如权限错误处理和全局模块迁移方案,以及版本回滚操作,确保用户能够灵活应对不同需求。
374 0
|
4月前
|
JavaScript Linux 内存技术
Debian 11系统下Node.js版本更新方法
Debian 11更新Node.js主要就是这三种方式,无论你是初涉其中的新手还是找寻挑战的专家,总有一种方式能满足你的需求。现在,你已经是这个
410 80
|
1月前
|
JavaScript 前端开发 安全
【逆向】Python 调用 JS 代码实战:使用 pyexecjs 与 Node.js 无缝衔接
本文介绍了如何使用 Python 的轻量级库 `pyexecjs` 调用 JavaScript 代码,并结合 Node.js 实现完整的执行流程。内容涵盖环境搭建、基本使用、常见问题解决方案及爬虫逆向分析中的实战技巧,帮助开发者在 Python 中高效处理 JS 逻辑。
|
3月前
|
JavaScript 前端开发 算法
流量分发代码实战|学会用JS控制用户访问路径
流量分发工具(Traffic Distributor),又称跳转器或负载均衡器,可通过JavaScript按预设规则将用户随机引导至不同网站,适用于SEO优化、广告投放、A/B测试等场景。本文分享一段不到百行的JS代码,实现智能、隐蔽的流量控制,并附完整示例与算法解析。
107 1
|
4月前
|
JavaScript 前端开发
怀孕b超单子在线制作,p图一键生成怀孕,JS代码装逼娱乐
模拟B超单的视觉效果,包含随机生成的胎儿图像、医疗文本信息和医院标志。请注意这仅用于前端开发学习
|
4月前
|
JavaScript
JS代码的一些常用优化写法
JS代码的一些常用优化写法
83 0
|
6月前
|
存储 JavaScript 前端开发
在NodeJS中使用npm包进行JS代码的混淆加密
总的来说,使用“javascript-obfuscator”包可以帮助我们在Node.js中轻松地混淆JavaScript代码。通过合理的配置,我们可以使混淆后的代码更难以理解,从而提高代码的保密性。
559 9
|
7月前
|
前端开发 JavaScript
【Javascript系列】Terser除了压缩代码之外,还有优化代码的功能
Terser 是一款广泛应用于前端开发的 JavaScript 解析器和压缩工具,常被视为 Uglify-es 的替代品。它不仅能高效压缩代码体积,还能优化代码逻辑,提升可靠性。例如,在调试中发现,Terser 压缩后的代码对删除功能确认框逻辑进行了优化。常用参数包括 `compress`(启用压缩)、`mangle`(变量名混淆)和 `output`(输出配置)。更多高级用法可参考官方文档。
548 11
|
6月前
|
JavaScript 前端开发 Java
js 垃圾回收机制的方法
JS回收机制方法讲解

热门文章

最新文章