美文网首页日常积累提升转型js
最全的数组操作方法,你造吗?

最全的数组操作方法,你造吗?

作者: grain先森 | 来源:发表于2018-12-30 21:04 被阅读378次

    在 JavaScript 中,对于数组的操作非常频繁,对应的 API 也很丰富 。ECMAScript 规范在每一版发布时,都会提供新的 API 来增强数组的操作能力,下面将详细介绍这些 API 的一些特性。


    ES5 新增的 9 个API


    forEach( callback, [thisArg] )

    在 ES5 之前,我们可以通过 for 和 for in 两种方式来遍历数组。

    ES5 引入了一个新方法 forEach,使数组遍历更加简洁,

    forEach需要传递两个参数,第一个参数是回调函数,是必选参数,第二个参数是一个对象,用来改变 callback 中的 this 指向,是可选参数。

    输出结果:

    a 0 ['a', 'b', 'c']
    b 1 ['a', 'b', 'c']
    c 2 ['a', 'b', 'c']

    callback 中传入了3个参数 v,i,r 分别表示当前元素、当前位置、数组对象。

    再看看使用 thisArg 的例子:

    输出结果:

    a 0
    b 1
    c 2

    不传 thisArgs 时,callback 中的 this 默认指向 window 对象,当传递 thisArg 时,callback 中的 this 就指向了 thisArg.

    因此这个参数的目的就是为了改变回调函数中的this指向。

    对于不支持 ES5 的浏览器,我们可以对 forEach 进行简单的扩展来兼容老的浏览器:


    filter( callback , [thisArg] )

    filter 是`过滤`的意思,所以这个方法的作用就是返回一个匹配过滤条件的新数组,其接收两个参数 callback 和 thisArg,callback也是回调函数,主要用于对元素进行条件匹配,thisArg 和 forEach中的 thisArg 作用一样,在这里就不重复了,看下面示例:

    打印newArr结果 ["a", "a"]

    没有filter的时候,要实现这个功能,我们事先要创建一个空的数组,把匹配到的元素再 push 进去,现在就不需要那么麻烦了,我们再看看对filter的扩展:

    可以看出,filter 将过滤的结果作为一个新数组返回,即使符合条件的元素只有一个,返回的也是数组 。为了更方便的对单个元素进行查询,ES6 在数组原型上提供了 find 方法,用于从数组中查询单个符合条件的元素,和 filter 不同的是,它返回的是单个元素。

    [2, 3, 5, 8, 9, 3].find(item => item == 3); // 3 

    需要注意的是,find 只返回第一个匹配到的元素,如果没有匹配到,则会返回 undefined 。和 filter 一样,find 也可以传递第 2 个参数,用于设置回调函数的 this 指针 。


    map( callback, [thisArg] )

    map 的作用是对原数组进行加工处理后并将其作为一个新数组返回,该方法同样接收两个参数,callback 是回调函数用于对数组进行加工处理,thisArg 和上面的一样。先看一个简单的例子:

    打印newArr[0] 结果:{w: 10, h: 10, area: 100}

    可以看出,newArr 返回的是增加了 area 属性的对象数组。这个方法非常实用,一般情况下,当一个ajax请求返回时,我们都要对其结果集进行过滤和校验等操作,这时 map 就派上用场了。我们再看看如果对 map 进行兼容性扩展:



    reduce ( callback, [initialValue] )

    reduce 在这里有`减少`的意思,其作用是对数组进行归并操作,换句话说就是对数组每一个元素进行累加,最终返回所有元素之和。 回调函数 callback 接收4个参数:

    previousValue - 存放的是上一次callback返回的结果,其初始值默认为数组的第一个元素。
    currentValue - 是当前元素 。默认从数组的第二个元素开始。
    currentIndex - 是当前元素位置 。
    array - 是当前数组。

    输出结果:

    1 2 1
    3 3 2
    6 4 3

    打印newArr ---> 10

    reduce 除过可以传递 callback 之外,还可以传递一个参数 initialValue ,作为数组累加的基数。当传了这个参数以后,callback 中的 previousValue 初始值就被置为 initialValue,reduce 也改为从数组的第一个元素开始遍历。

    输出结果:

    100 1 0
    101 2 1
    103 3 2
    106 4 3

    打印newArr ---> 110

    从结果可以看出,reduce 最终返回的是: previousValue + 数组本身归并计算的结果。对 reduce 的 polyfill 实现如下:



    reduceRight ( callback, [initialValue] )

    和 reduce 的作用完全相同,唯一的不同是,reduceRight 是从右至左遍历数组的元素。



    some ( callback, [thisArg] )

    some 是`某些、一些`的意思,其作用是对数组中的每一项执行回调函数,如果该函数对任一项返回 true,则停止遍历,并返回 true 。

    输出结果:

    1 0 [1, 2, 3, 4]
    2 1 [1, 2, 3, 4]
    3 2 [1, 2, 3, 4]

    打印 result ---> true

    some 检测整个数组,只要当arr中有一个元素符合条件 item>2 就停止检测和遍历,并返回 true,以表示检测到目标。这和我们在 for 循环中使用 break 语言的作用有点类似。

    对于 some 的兼容性扩展如下:



    every (callback, [thisArg])

    every 是`每一个`的意思,其作用是对数组中的每一项执行回调函数,如果该函数对每一项都返回 true,则返回 true 。

    输出结果:

    1 0 [1, 2, 3, 4]
    2 1 [1, 2, 3, 4]
    3 2 [1, 2, 3, 4]

    打印result ---> false

    当检测第3个元素时,item<3 为 false,停止检测,并返回 false,这说明every在检测元素时,要求每一个元素都要符合条件 item<3,如果有一个不符合就停止检测,并返回false。(你可以测试 item<5 时的运行结果,返回值一定是 true ) 。

    那 every 到底有什么作用呢? 当一个 for 循环使用了 break 语句后,我们想知道 for 循环是否正常的执行完时, 我们一般会通过检测for中的索引 i==arr.length 来判断,因此every 的作用就体现在这里。

    下面是对于 every 的兼容性扩展:



    indexOf[searchElement, [fromIndex]]

    indexOf() 用于查询数组元素对应的索引位置,可以传递两个参数,第一个参数是要匹配的元素,必须是简单数据类型。第二个参数是指定查询的起始位置。

    // 默认从索引0的位置开始
    [1, 2, 3, 5, 2].indexOf(2);// 1
    // 指定从索引3的位置开始
    [1, 2, 3, 5, 2].indexOf(2, 3);// 4

    ndexOf() 返回的是元素在数组中的位置 。如果只想知道数组中是否存在某个元素,而不关心元素的位置,也可以使用 ES6 提供的 includes() 方法来判断。

    let a = [1, 2, 3];
    a.includes(1);// true
    a.includes(1, 1);// false


    includes() 也是数组原型上的方法, 和 indexOf() 的传参是一样的。

    需要注意的是,indexOf() 适用于数组元素是简单类型的情况,而无法检索对象数组的元素位置。

    let arr = [{c: 1}, {c: 2}];// 对象数组
    arr.indexOf({c: 1});// -1

    对于这个问题,可以使用 forEach() 来遍历数组,当找到符合条件的元素时,就可以获取到对应的数组下标,而在 ES6 中,可以使用 findIndex() 达到同样的目的。

    findIndex() 也是用于查询数组元素的位置,和 indexOf() 不同的是,它可以检索对象数组的元素位置,但需要通过回调函数来指定匹配的元素。

    //简单数组
    [1, 2, 3, 5].findIndex(item => item == 3);// 2
    //对象数组
    [{id: 1}, {id: 3}, {id: 5}].findIndex(item => item.id == 3);// 1



    lastIndexOf[searchElement, [fromIndex]]

    和 indexOf() 的作用完全相同,唯一的不同是,lastIndexOf() 是从右至左检索数组元素。

    感兴趣的小伙伴,可以关注公众号【grain先森】,回复关键词 【181230】,获取【前端教程】,更多关键词玩法期待你的探索~

    相关文章

      网友评论

        本文标题:最全的数组操作方法,你造吗?

        本文链接:https://www.haomeiwen.com/subject/sqlblqtx.html