javascript数组的遍历

这一节我们一起整理一下数组的遍历,目前来说遍历数组的方式非常多,首先我们来列举一下有哪些:

  • for
  • for-in
  • for-of
  • forEach
  • map
  • some
  • every
  • filter
  • find
  • findIndex
  • reduce
  • reduceRight
  • keys
  • entries

有些我们之前就认识,有些也是我最近学到的
按照惯例,我们需要先定义一个被测试的数组:

let arr = Array.of(1, 'str', false, []);

// 注意这句,我目的是让索引值为4的那一项为空值
arr[5] = {};

// 所以我们得到的数组结构为
[1, 'str', false, [],  , {}]

我们正式开始:


for

for (let i = 0, len = arr.length; i < len; i++) {
    console.log(i, arr[i])
}

打印的结果为:

0 -> 1
1 -> 'str'
2 -> false
3 -> []
4 -> undefined
5 -> Object {}

根据结果我们分析为:

  1. 索引值i为Number类型
  2. 遍历过程中如果遇到空值,依然会执行,返回undefined

for-in

for (let i in arr) {
    console.log(i, arr[i])
}

打印的结果为:

'0' -> 1
'1' -> 'str'
'2' -> false
'3' -> []
'5' -> Object {}

大体上和for循环比较类似,但还是有所区别的

  1. 索引值i为String类型(这点我也不是很懂为什么...)
  2. 遍历过程中如果遇到空值,则会跳过

for-of

for (let i of arr) {
    console.log(i)
}

打印的结果为:

1
'str'
false
[]
undefined
Object {}
  1. 与前两个不同的是,该循环的i是被遍历数组的键值
  2. 遍历过程中如果遇到空值,依然会执行,返回undefined

forEach

arr.forEach((value, index, arr) => {
    console.log(value)
})

打印的结果为:

1
'str'
false
[]
Object {}
  1. 首先,forEach无返回值,所以回调函数也不需要return
  2. 回调函数的参数分别为当前的值(value), 索引值(index), 被遍历的数组(arr)
  3. 遍历过程中如果遇到空值,跳过

map

let result = arr.map((value, index, arr) => {
    console.log(value)
    return value
})

打印的结果为:

1
'str'
false
[]
Object {}
  1. map函数会根据回调函数中return的值(为新数组的值)得到一个新的数组
  2. 回调函数的参数分别为当前的值(value), 索引值(index), 被遍历的数组(arr)
  3. 遍历过程中如果遇到空值,跳过

所以如果需要根据原数组的值得到一个相关联的新数组时,比较适合使用map
例:

let newarr = [1, 2, 3].map(value => value * 2)

以上代码可以得到这样一个数组:

[2, 4, 6] // newarr

some

some用于检测数组中的某一项是否符合条件

let result = arr.some((value, index, arr) => {
    return typeof value == 'string'
})

根据被测试的这个数组,我们得到的结果是:

true // result

因为索引值为1的那一项确实为String类型

  1. 返回Boolean类型的值
  2. 回调函数的参数分别为当前的值(value), 索引值(index), 被遍历的数组(arr)
  3. 回调函数需要返回true或者false
  4. 遍历过程中如果某个回调函数返回true时,停止遍历,result得到true
  5. 如果直到遍历结束所有回调函数均返回false,那么result便为false
  6. 遍历过程中如果遇到空值,跳过

every

every与some相反,用于检测数组中的每一项是均否符合条件

let result = arr.every((value, index, arr) => {
    return typeof value == 'string'
})

很显然,根据被测试的这个数组,我们得到的结果是:

false // result

看懂some之后every其实也就明白是做什么的了

  1. 返回Boolean类型的值
  2. 回调函数的参数分别为当前的值(value), 索引值(index), 被遍历的数组(arr)
  3. 回调函数需要返回true或者false
  4. 遍历过程中如果某个回调函数返回false时,停止遍历,result得到false
  5. 如果直到遍历结束所有回调函数均返回true,那么result便为true
  6. 遍历过程中如果遇到空值,跳过

filter

let result = arr.filter((value, index, arr) => {
    return typeof value == 'object'
})

打印的结果为:

[Array[0], Object {}] // result
  1. filter会根据回调函数中return的值(Boolean值)得到一个新的数组
  2. 回调函数需要返回一个Boolean值,为true时,filter的结果数组中将会得到该值,为false时跳过
  3. 回调函数的参数分别为当前的值(value), 索引值(index), 被遍历的数组(arr)
  4. 遍历过程中如果遇到空值,跳过

说下filter与map的区别:

  • 第一点当然是回调函数返回值的不同,filter的回调函数返回布尔值,map的回调函数是将新数组所需要的值返回出来,所以filter只能选择要或者不要,而map可以给值做相应的调整,比如数组[1, 2, 3]我要得到一个新数组[2, 4, 6]时,使用map会很方便的做到。
  • 第二点是filter可以舍弃掉值,即比如数组[1, 2, 3]我们可以做到得到一个内容[2, 3]的数组,只要在回调函数中return value > 1即可,而map做不到,正常情况下被操作的数组与得到的新数组的length相等,不过length这里在有数组中有空值的情况下会不等,因为filter会跳过空值,所以本例子中被测试数组的length6,而filter即使回调函数全部返回true,得到的新数组的length也为5

find

find顾名思义是要找什么东西,所以不难想象find的返回值是被遍历数组中的某一项,我们来试试从测试数组中找String类型的值:

let result = arr.find((value, index, arr) => {
    return typeof value == 'string'
})

打印的结果为:

'str' // result

有一点要注意的是,他只能从头开始找到最先找到的那个,并非全部找出来
所以以下这种情况下只会找到1

let res = [1, 2, 3, 4, 5].find(val => val < 9) // res -> 1
  1. find会根据回调函数中return的值(Boolean值)得到return true的那个键值
  2. 当回调函数返回true之后,停止遍历,所以只会得到一个结果
  3. 回调函数的参数分别为当前的值(value), 索引值(index), 被遍历的数组(arr)
  4. 遍历过程中如果遇到空值,依然会执行,返回undefined

findIndex

看完find之后,我相信findIndex也就明白了,用法是几乎一样

let result = arr.findIndex((value, index, arr) => {
    return typeof value == 'string'
})

因为'str'的索引值为1,所以打印的结果为:

1 // result
  1. findIndex会根据回调函数中return的值(Boolean值)得到return true的那个键值的索引值
  2. 当回调函数返回true之后,停止遍历,所以只会得到一个结果
  3. 回调函数的参数分别为当前的值(value), 索引值(index), 被遍历的数组(arr)
  4. 遍历过程中如果遇到空值,依然会执行,返回undefined

reduce

reduce比较有意思,我们先看测试代码再做分析:

let arr2 = [1.2, 3.3, 5.4, 3.2, 5.3, 4.1, 4.9];
let result = arr2.reduce((prev, next) => {
    let p = Math.abs(prev - 5), n = Math.abs(next - 5)
    return p < n ? prev : next
})

这段代码的意思是这样的:
arr2中找到最接近5的那个值回调函数接收2个值
第一次遍历时传递的是索引值为01的两个值,本例子中实为1.23.3,然后回调函数中实为返回了3.3这个值
第二次遍历,注意,传递的值变成了前一次遍历return的值与下一个索引值相关的值,既3.3与索引值为25.4,然后我判断下来说5.4更接近5,所以返回了5之后的遍历以此类推,直到结束
所以result最终结果为:

4.9 // result

还有个reduceRight方法我就不写了,我测试下来和reduce区别仅在于reduceRight是从数组最末位倒序执行


keys

数组的实例方法,返回一个数组的遍历器:

for (let i of arr.keys()) {
    console.log(i)
}

打印结果为:

0
1
2
3
4
5
  1. 可以用for of取到数组的索引
  2. 遍历过程中如果遇到空值,会执行
  3. 和for循环表现一致

entries

同样也是数组的实例方法,返回一个数组的遍历器:

for (let i of arr.entries()) {
    console.log(i)
}

打印结果为:

[0, 1]
[1, 'str']
[2, false]
[3, Array [0]]
[4, undefined]
[5, Object {}]
  1. 可以用for of取到数组的索引和键值
  2. 循环得到的结果是Array类型,[0]为索引,[1]为键值
  3. 遍历过程中如果遇到空值,会执行,键值为undefined

当然你要是喜欢,可以用解构赋值的方式:

for (let [index, value] of arr.entries()) {
    console.log(index, value)
}

关于数组的解构赋值这里就不多说了...


有一点要提的是,关于空值的处理,实在是没什么规律可以找,有些处理方式是跳过,有些则是返回undefined,所以保险起见,还是尽量别在数组中出现空值的情况
好了,以上学习资料仅供参考,如果有坑请以各大官方资料为准...

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

推荐阅读更多精彩内容