面试时经常被问到,记录一下数组的所有遍历方法(持续更新中…)
截止目前(2020年2月28日),数组的遍历方法共15个:
1 2 3 4
| ES5: for、forEach、every 、some、 filter、map、reduce、reduceRight、for...in ES6: find、findIndex、keys、values、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)) console.log(arr.every((currentValue, index, array) => currentValue > 0))
|
some
测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回一个布尔值
ps:若收到一个空数组,此方法在一切情况下都会返回 false
1 2 3
| let arr = [1, 2, 3] console.log(arr.some((currentValue, index, array) => currentValue > 1)) console.log(arr.some((currentValue, index, array) => currentValue > 4))
|
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))
|
map
创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
1 2
| let arr = [1, 2, 3] console.log(arr.map((currentValue, index, array) => currentValue * 2))
|
reduce
对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。
1 2 3 4 5 6 7 8 9
| let arr = [1, 2, 3] let res = arr.reduce((acc, cur, idx, src) => { return acc + cur }) console.log(res)
|
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) }
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)) console.log(arr.find((currentValue, index, array) => currentValue > 10))
|
findIndex
返回数组中满足提供的测试函数的第一个元素的索引
ps:如果数组中没有元素符合函数测试条件,则返回-1
1 2 3
| let arr = [1, 2, 3] console.log(arr.findIndex((currentValue, index, array) => currentValue > 20)) console.log(arr.findIndex((currentValue, index, array) => currentValue > 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) }
|
对比
*是否修改原数组是指:在该方法的遍历中做操作,是否会影响原数组
*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使用