前端百题斩【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


相关文章
|
4天前
|
前端开发 BI
jeecgboot中前端使用带有参数报表的方法
jeecgboot中前端使用带有参数报表的方法
12 0
|
5天前
|
自然语言处理 前端开发 Java
深入浅出JVM(六)之前端编译过程与语法糖原理
深入浅出JVM(六)之前端编译过程与语法糖原理
|
4天前
|
前端开发 JavaScript 开发者
实用技巧:提高前端开发效率的5个方法
提高前端开发效率是每个开发者都追求的目标。本文将介绍5个实用的技巧,帮助前端开发者提升工作效率:使用代码片段加速开发、合理利用浏览器开发者工具、充分利用现有框架和库、使用自动化构建工具、保持学习和不断优化工作流程。
|
4天前
|
JavaScript 前端开发
深入了解前端框架Vue.js的响应式原理
本文将深入探讨Vue.js前端框架的核心特性之一——响应式原理。通过分析Vue.js中的数据绑定、依赖追踪和虚拟DOM等机制,读者将对Vue.js的响应式系统有更深入的理解,从而能够更好地利用Vue.js构建灵活、高效的前端应用。
|
7天前
|
前端开发 测试技术
前端自动化测试中的快照测试原理
快照测试用于前端自动化测试,通过比较当前应用状态与预存预期快照来检测UI变化。流程包括设置测试环境、捕获屏幕快照、保存预期快照、比较快照及处理差异。当快照比较出现差异时,测试工程师审查判断是否为预期变化或错误,确保应用一致性。这种方法在重构、样式更改和跨浏览器测试时提供有效回归测试,减少手动验证工作。
|
15天前
|
JavaScript 前端开发 数据安全/隐私保护
优秀的前端框架vue,原理剖析与实战技巧总结【干货满满】(二)
优秀的前端框架vue,原理剖析与实战技巧总结【干货满满】(二)
|
15天前
|
JavaScript 前端开发 Python
优秀的前端框架vue,原理剖析与实战技巧总结【干货满满】(一)
优秀的前端框架vue,原理剖析与实战技巧总结【干货满满】(一)
|
15天前
|
前端开发 JavaScript 开发者
【Web 前端】数组迭代的方法有哪些?
【4月更文挑战第22天】【Web 前端】数组迭代的方法有哪些?
|
15天前
|
前端开发 JavaScript 索引
【Web 前端】数组的基本操作方法?
【4月更文挑战第22天】【Web 前端】数组的基本操作方法?
|
15天前
|
前端开发
【Web 前端】对于数组去重都有哪些方法?
【4月更文挑战第22天】【Web 前端】对于数组去重都有哪些方法?