前端百题斩【019】——数组中方法原理早知道

简介: 前端百题斩【019】——数组中方法原理早知道

js的Array对象可以调用很多方法,每一个方法都有其特殊的用途,但是很多情况下我们仅仅会使用这么高级方法,多于其实现过程知之甚少,本节就数组中的常用方法map、filter、reduce进行实现,帮助了解其原理。


19.1 map


640.jpg


19.1.1 基础


map() 方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。

  1. map方法的用法如下所示:


const new_array = arr.map(function callback(currentValue[, index[, array]]) {
 // ……
}[, thisArg])
  1. 小试牛刀


const arr = [1, 2, 3, 4];
const newArr = arr.map(value => value * 3);
console.log(arr); // [ 1, 2, 3, 4 ] 原数组不变
console.log(newArr); // [ 3, 6, 9, 12 ]

19.1.2 实现


map做的事情很单纯,就是处理每个元素然后返回一个新的数组,下面就来看看怎样实现自己的map函数。实现步骤如下所示:


  1. 判断输入的第一个参数是不是函数
  2. 获取需要处理的数组内容
  3. 新建一个新数组用于装载新的内容
  4. 对数组中每个值进行处理(注意改变this指向)
  5. 返回结果


Array.prototype.myMap = function(fn) {
    // 判断输入的第一个参数是不是函数
    if (typeof fn !== 'function') {
        throw new TypeError(fn + 'is not a function');
    }
    // 获取需要处理的数组内容
    const arr = this;
    const len = arr.length;
    // 新建一个空数组用于装载新的内容
    const temp = new Array(len);
    // 对数组中每个值进行处理
    for (let i = 0; i < len; i++) {
        // 获取第二个参数,改变this指向
        let result = fn.call(arguments[1], arr[i], i, arr);
        temp[i] = result;
    }
    // 返回新的结果
    return temp;
}
const arr = [1, 2, 3, 4];
const newArr = arr.myMap(value => value * 3);
console.log(arr); // [ 1, 2, 3, 4 ] 原数组不变
console.log(newArr); // [ 3, 6, 9, 12 ]

上述就是map的实现流程,并且经过验证与原生的map方法的结果一致。


19.2 filter


640.jpg


19.2.1 基础


filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。

  1. filter方法的用法如下所示:


const newArray = arr.filter(callback(element[, index[, array]])[, thisArg])
  1. 小试牛刀
const arr = [1, 2, 3, 4];
const newArr = arr.filter(value => value > 2);
console.log(arr); // [ 1, 2, 3, 4 ]
console.log(newArr); // [ 3, 4 ]

19.2.2 实现


filter函数做的事情就是过滤出符合条件的元素,对于filter的实现步骤和map的基本一致,不同之处在于其在数组中处理每个值的时候稍有区别。


Array.prototype.myFilter = function (fn) {
    if (typeof fn !== 'function') {
        throw new TypeError(`${fn} is not a function`);
    }
    // 获取该数组
    const arr = this;
    // 获取该数组长度
    const len = this.length >>> 0;
    // 新建一个新的数组用于放置该内容
    const temp = [];
    // 对数组中每个值进行处理
    for (let i = 0; i < len; i++) {
        // 处理时注意this指向
        const result = fn.call(arguments[1], arr[i], i, arr);
        result && temp.push(arr[i]);
    }
    return temp;
}
const arr = [1, 2, 3, 4];
const newArr = arr.myFilter(value => value > 2);
console.log(arr); // [ 1, 2, 3, 4 ]
console.log(newArr); // [ 3, 4 ]


19.3 reduce


640.jpg


19.3.1 基础


reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。


  1. reduce方法的用法如下所示:


const result = arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
  1. 小试牛刀


const arr = [1, 2, 3, 4];
const result = arr.reduce((accumulator, value) => accumulator + value);
console.log(result); // 10

19.3.2 实现


reduce为数组中的每一个元素依次执行callback函数,下面就来看看怎样实现自己的filter函数。实现步骤如下所示:


  1. 判断输入的第一个参数是不是函数
  2. 获取需要处理的数组内容
  3. 获取初始值
  4. 依次处理后续数组中的元素
  5. 返回累加器处理的结果


Array.prototype.myReduce = function(fn) {
    if (typeof fn !== 'function') {
        throw new TypeError(`${fn} is not a function`);
    }
    const arr = this;
    const len = arr.length >>> 0;
    let value;// 最终返回的值
    let k = 0;// 当前索引
    if (arguments.length >= 2) {
        value = arguments[1];
    } else {
        // 当数组为稀疏数组时,判断数组当前是否有元素,如果没有索引加一
        while (k < len && !( k in arr)) {
            k++;
        }
        // 如果数组为空且初始值不存在则报错
        if (k >= len) {
            throw new TypeError('Reduce of empty array with no initial value');
        }
        value = arr[k++];
    }
    while (k < len) {
        if (k in arr) {
            value = fn(value, arr[k], k, arr);
        }
        k++;
    }
    return value;
}
const arr = [1, 2, 3, 4];
const result = arr.myReduce((accumulator, value) => accumulator + value);
console.log(result); // 10


相关文章
|
26天前
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
|
16天前
|
移动开发 缓存 前端开发
深入理解前端路由:原理、实现与应用
本书《深入理解前端路由:原理、实现与应用》全面解析了前端路由的核心概念、工作原理及其实现方法,结合实际案例探讨了其在现代Web应用中的广泛应用,适合前端开发者和相关技术人员阅读。
|
25天前
|
缓存 JavaScript 前端开发
JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用
本文深入讲解了 JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用。
39 5
|
28天前
|
前端开发 开发者
本文将深入探讨 BEM 的概念、原理以及其在前端开发中的应用
BEM(Block-Element-Modifier)是一种前端开发中的命名规范和架构方法,旨在提高代码的可维护性和复用性。通过将界面拆分为独立的模块,BEM 提供了一套清晰的命名规则,增强了代码的结构化和模块化设计,促进了团队协作。本文深入探讨了 BEM 的概念、原理及其在前端开发中的应用,分析了其优势与局限性,为开发者提供了宝贵的参考。
47 8
|
23天前
|
缓存 前端开发 JavaScript
JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式
本文深入解析了JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式(Hash路由和History路由)、优点及挑战,并通过实际案例分析,帮助开发者更好地理解和应用这一关键技术,提升用户体验。
60 1
|
28天前
|
监控 前端开发 jenkins
Jenkins 在前端项目持续部署中的应用,包括其原理、流程以及具体的实现方法
本文深入探讨了Jenkins在前端项目持续部署中的应用,涵盖其基本原理、流程及具体实现方法。首先介绍了Jenkins的基本概念及其在自动化任务中的作用,随后详细解析了从前端代码提交到生产环境部署的全过程,包括构建、测试、部署等关键步骤。最后,强调了持续部署中的代码质量控制、环境一致性、监控预警及安全管理等注意事项,旨在帮助开发者高效、安全地实施持续部署。
54 5
|
2月前
|
JavaScript 前端开发 算法
前端优化之超大数组更新:深入分析Vue/React/Svelte的更新渲染策略
本文对比了 Vue、React 和 Svelte 在数组渲染方面的实现方式和优缺点,探讨了它们与直接操作 DOM 的差异及 Web Components 的实现方式。Vue 通过响应式系统自动管理数据变化,React 利用虚拟 DOM 和 `diffing` 算法优化更新,Svelte 通过编译时优化提升性能。文章还介绍了数组更新的优化策略,如使用 `key`、分片渲染、虚拟滚动等,帮助开发者在处理大型数组时提升性能。总结指出,选择合适的框架应根据项目复杂度和性能需求来决定。
|
2月前
|
存储 前端开发 JavaScript
前端的全栈之路Meteor篇(四):RPC方法注册及调用-更轻量的服务接口提供方式
RPC机制通过前后端的`callAsync`方法实现了高效的数据交互。后端通过`Meteor.methods()`注册方法,支持异步操作;前端使用`callAsync`调用后端方法,代码更简洁、易读。本文详细介绍了Methods注册机制、异步支持及最佳实践。
|
2月前
|
人工智能 前端开发 JavaScript
拿下奇怪的前端报错(一):报错信息是一个看不懂的数字数组Buffer(475) [Uint8Array],让AI大模型帮忙解析
本文介绍了前端开发中遇到的奇怪报错问题,特别是当错误信息不明确时的处理方法。作者分享了自己通过还原代码、试错等方式解决问题的经验,并以一个Vue3+TypeScript项目的构建失败为例,详细解析了如何从错误信息中定位问题,最终通过解读错误信息中的ASCII码找到了具体的错误文件。文章强调了基础知识的重要性,并鼓励读者遇到类似问题时不要慌张,耐心分析。
|
2月前
|
缓存 JavaScript 前端开发
拿下奇怪的前端报错(三):npm install卡住了一个钟- 从原理搞定安装的全链路问题
本文详细分析了 `npm install` 过程中可能出现的卡顿问题及解决方法,包括网络问题、Node.js 版本不兼容、缓存问题、权限问题、包冲突、过时的 npm 版本、系统资源不足和脚本问题等,并提供了相应的解决策略。同时,还介绍了开启全部日志、使用替代工具和使用 Docker 提供 Node 环境等其他处理方法。
1074 0