JavaScript花样百出的数组遍历

47 阅读5分钟

前言

本文章源自《JavaScript知识小册》专栏,感兴趣的话还请关注点赞收藏.

上一篇文章:《JavaScript解构赋值

下一篇文章:《JavaScript中的伪数组

花样百出的数组遍历

在JS中遍历数组的方式有很多,本文仅做知识索引,方便需要用时可以查找

for循环

首先是最简单的for...i++

let arr = [1,2,3]

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

输出1 2 3

forEach()

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

forEach相当于是定义一个函数来逐个遍历数组,这个函数有3个参数,elem表示当前元素,index表示当前元素对应的下标,array表示当前遍历的数组本身。

forEachfor...i++还有个区别在于,forEach中无法使用breakcontinue来中断循环。

map()

forEach只是对数组元素的循环,map除了遍历数组中每个元素,还可以根据回调操作将数组中的元素做处理,形成新的返回值,最后构建出新的数组。

let arr = [1, 2, 3]
let result = arr.map((value) => {
        value = `seq ${value}`
    return value
})
console.log(result)

输出 ["seq 1", "seq 2", "seq 3"],原本是number类型的数组,通过map构建为新的string类型的数组

filter()

filter除了遍历数组中的每个元素,还可以根据特定条件对数组中的元素进行筛选,只有符合条件的元素才会被选中,最后形成新的数组并返回

let result1 = arr.filter((value) => {
    return value === 2
})
console.log(result1)

输出[2]

some()

some则是遍历数组中是否有符合条件的元素,只要有一个元素符合条件,就会返回true,否则返回false

let isHave = arr.some((value) => {
    return value === 2
})

输出true

every()

every作用跟some一样,但是比some更苛刻,需要数组中每个元素都符合条件,才返回true,否则返回false

let isAllHave = arr.every((value) => {
    return value === 2
})

输出false

reduce()

reduce相当于接收一个函数作为累加器

let arr = [1,2,3]
let sum = arr.reduce((prev,cur,index, array) => {
    return prev + cur 
}, 0)
console.log('reduce', sum)

输出6,相当于1+2+3=6。reduce方法有两个参数,第一个参数是一个函数,第二个参数是初始值。因为reduce重点是做一个累加使用,而且仅仅是为了计算出arr数组里所有元素的总和,所以这里初始值设置为0。也就是相当于0+1+2+3=6。而第一个参数则表示数组元素累加时所回调的函数。

prev表示上一次回调的时候所对应的返回值,因为初始值是0,所以prev一开始等于0

cur表示当前正在处理的数组元素

index表示当前正在处理的数组元素对应的索引

array表示源数组

return prev + cur 其实就表示了将上一次累加的结果,和本次正在处理的数组元素做一个累加,最后返回。也可以根据业务逻辑做一些特殊处理,比如当前数组中元素是奇数的话,则不累加,直接return prev,是偶数的话才return prev + cur

reduce也可以不仅仅是做累加操作,还可以是计算出数组中最大值

let max = arr.reduce((prev, cur) => {
    return Math.max(prev, cur)
})
console.log(max)

输出3,原理也很简单,做数组元素累加时,prev是上一次累加的结果,但也可以不做累加,而是把prev看做是上一次数组元素,cur看做是当前正在处理的数组元素,那么只需要在每次遍历数组元素时,取prevcur两者最大值并返回,本次返回的最大值,将作为下一次遍历时的prev,然后与cur再作比较,最后就能得到数组中最大值。

reduce也可以做数组去重用

let arr = [1,2,2,3,3]
let set = arr.reduce((prev, cur) => {
    prev.indexOf(cur) === -1 && prev.push(cur)
    return prev
}, [])
console.log(set)

输出[1,2,3],同样是会循环数组所有元素,但这里把prev初始值设为了[]cur是当前正处理的数组元素,每次循环回调(prev,cur) => {}时,都检查一遍prev是否已包含了当前数组元素,不是的话才把cur添加到prev中。

for...in... [不建议]

let arr = [1,2,3]
for (let index in arr) {
    console.log(index, arr[index])
}

输出0 1 1 2 2 3

遍历数组看起来没什么问题,但是要注意的是for...in... 不仅会遍历出数组的值,同时也会遍历出prototyp下自定义的方法

比如在Array.prototype上加上print方法

Array.prototype.print = () => {
    console.log('print')
}

再执行上边的代码,输出则不止是 0 1 1 2 2 3 同时也会把print()给打印出来 print ƒ () { console.log('print'); }

所以其实不建议使用for...in...遍历数组

find()

find是返回数组中第一个满足条件的元素

let arr
let findRes = arr.find((value) => {
    return value === 2
})
console.log('find', findRes)

输出find 2

findIndex()

findIndex是返回数组中第一个满足条件的元素的下标

let arr
let findRes = arr.findIndex((value) => {
    return value === 2
})
console.log('findIndex', findRes)

输出findIndex 2

for...of

for...offor...in一样可以用来遍历数组,但是for...of不会像for...in...那样把prototype的自定义方法也遍历出来

let arr = [1,2,3]
for (const item of arr) {
    console.log(item)
}

输出1 2 3

values()

values这个方法其实是返回数组中的所有值,然后我们可以基于返回的所有值进行遍历

let arr = [1, 2, 3]
for (const val of arr.values()) {
    console.log(val)
}

输出1 2 3,与上边for...of结果无异

keys()

key这个方法则相当于返回数组中的所有值的下标,然后我们遍历的话,则变成了在遍历下标

let arr = [1, 2, 3]
for (const val of arr.values()) {
    console.log(val)
}

输出0 1 2

entries()

entries则相当于是keysvalues结合,我们遍历的时候既可以取得数组元素下标,也可以取得数组元素

for (const [index, item] of arr.entries()){
    console.log(index, item)
}

输出0 1 1 2 2 3