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

在 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】,获取【前端教程】,更多关键词玩法期待你的探索~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容