数组里面的那些遍历方法

面试时经常被问到,记录一下数组的所有遍历方法(持续更新中…)

截止目前(2020年2月28日),数组的遍历方法共15个:

1
2
3
4
ES5:
for、forEach、every 、some、 filtermap、reduce、reduceRight、for...in
ES6:
find、findIndex、keysvalues、entries、for...of

经典遍历方法

for

1
2
3
4
5
6
7
8
9
10
let arr = [1, 2, 3]
for (let i = 0; i < arr.length; i++) {
// do something
}

// 优化版写法
// 使用临时变量,将长度缓存起来,避免重复获取数组长度
for (let i = 0, len = arr.length; i < len; i++) {
// do something
}

forEach

针对每一个元素执行提供的函数。会修改原来的数组,不会返回执行结果

1
2
3
4
5
6
let arr = [1, 2, 3]
arr.forEach((currentValue, index, array) => {
// currentValue 当前元素
// index 索引
// array 正在操作的数组
})

every

测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值

ps:若收到一个空数组,此方法在一切情况下都会返回 true

1
2
3
let arr = [1, 2, 3]
console.log(arr.every((currentValue, index, array) => currentValue > 1)) // false
console.log(arr.every((currentValue, index, array) => currentValue > 0)) // true

some

测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回一个布尔值

ps:若收到一个空数组,此方法在一切情况下都会返回 false

1
2
3
let arr = [1, 2, 3]
console.log(arr.some((currentValue, index, array) => currentValue > 1)) // true
console.log(arr.some((currentValue, index, array) => currentValue > 4)) // false

filter

创建一个新数组, 返回通过所提供函数实现的测试的所有元素

ps:如果数组中没有元素符合函数测试条件,则返回空数组

1
2
3
let arr = [1, 2, 3]
console.log(arr.filte((currentValue, index, array) => currentValue > 4)) // []
console.log(arr.filter((currentValue, index, array) => currentValue > 1)) // [2, 3]

map

创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。

1
2
let arr = [1, 2, 3]
console.log(arr.map((currentValue, index, array) => currentValue * 2)) // [2, 4, 6]

reduce

对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。

1
2
3
4
5
6
7
8
9
let arr = [1, 2, 3]
let res = arr.reduce((acc, cur, idx, src) => {
// Accumulator (acc) (累计器),它是上一次调用回调时返回的累积值,如果没有return值则为undefined
// Current Value (cur) (当前值)
// Current Index (idx) (当前索引)
// Source Array (src) (源数组)
return acc + cur
})
console.log(res) // 6

reduceRight

与reduce基本相同,唯一的区别就是:reduceRight是从右向左遍历

for…in

遍历数组循环出key

1
2
3
4
5
6
7
8
9
let arr = [1, 2, 3]
for (const key in arr) {
console.log(key) // 0 1 2
}

let obj = { name: '呆呆', age: 17, job: 'coder' }
for (const key in obj) {
console.log(key)
}

es6后新增遍历方法

find

返回数组中满足提供的测试函数的第一个元素的值

ps:如果数组中没有元素符合函数测试条件,则返回undefined

1
2
3
let arr = [1, 2, 3]
console.log(arr.find((currentValue, index, array) => currentValue > 0)) // 1
console.log(arr.find((currentValue, index, array) => currentValue > 10)) // undefined

findIndex

返回数组中满足提供的测试函数的第一个元素的索引

ps:如果数组中没有元素符合函数测试条件,则返回-1

1
2
3
let arr = [1, 2, 3]
console.log(arr.findIndex((currentValue, index, array) => currentValue > 20)) // -1
console.log(arr.findIndex((currentValue, index, array) => currentValue > 0)) // 0

keys

返回一个由一个给定对象的自身可枚举属性组成的数组

1
2
3
4
5
let arr = [1, 2, 3]
console.log(Object.keys(arr)) // ["0", "1", "2"]

let arr = { name: '呆呆', age: 17, job: 'coder' }
console.log(Object.keys(arr)) //  ["name", "age", "job"]

values

返回一个给定对象自身的所有可枚举属性值的数组

1
2
3
4
5
let arr = [1, 2, 3]
console.log(Object.values(arr)) // [1, 2, 3]

let arr1 = { name: '呆呆', age: 17, job: 'coder' }
console.log(Object.values(arr1)) //  ["呆呆", 17, "coder"]

entries

返回一个给定对象自身可枚举属性的键值对数组

1
2
3
4
5
let arr = [1, 2, 3]
console.log(Object.entries(arr)) // [["0", 1],["1", 2],["2", 3]]

let arr1 = { name: '呆呆', age: 17, job: 'coder' }
console.log(Object.entries(arr1)) //  [["name", "呆呆"],["age", 17],["job", "coder"]]

for…of

遍历数组循环出value

ps:for…of不能循环普通的对象

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

对比

*是否修改原数组是指:在该方法的遍历中做操作,是否会影响原数组
*ps:此处的原数组值均为基本数据类型即数字、字符串数组
*pps:对象数组会修改里面的内容
*ppps:Object对象的真实数据存储在堆内存中,它在栈内存中存储的是变量名和堆内存的位置。 在循环方法里操作的obj对象,实际操作的是该对象在堆内存的地址,由于是对该地址所在的对象进行字段值修改,所以数组里的obj对象相应改变。

方法 是否修改原数组 是否有返回值 返回值内容 是否可以跳出循环
for break可跳出
forEach
every Boolean
some Boolean
filter Array(没有符合的过滤条件返回空数组)
map Array(需要手动return,否则返回内容是undefined)
reduce Any
reduceRight Any
for…in break可跳出
find 找到则返回值,否则返回undefined
findIndex Number
keys Array
values Array
entries Array
for…of break可跳出

用途

// 单纯地遍历
Array.prototype.forEach

// 检测数组中是否有元素符合条件
Array.prototype.some

// 检测数组中是否所有元素符合条件
Array.prototype.every

// 用来将一个列表转换成另一个等长的列表
Array.prototype.map

// 用来将一个列表转换成一个值
Array.prototype.reduce

// 从列表中找出符合条件的一个元素
Array.prototype.find

// 从列表中找出符合条件的若干元素
Array.prototype.filter

// 拍平列表
Array.prototype.flat

// map 和 flat 的结合,适合用来将一个列表转换成另一个不等长的列表
Array.prototype.flatMap

哪些会修改原数组

改变数组自身内容的方法有7个:push、pop、shift、unshift、splice、sort和reverse

不会改变原数组的有:concat、join、slice、map、filter、forEach、some、every、reduce

更多api使用


数组里面的那些遍历方法
https://xypecho.github.io/2020/02/28/数组里面的那些遍历方法/
作者
很青的青蛙
发布于
2020年2月28日
许可协议