数组遍历的几种方法
.forEach() 的主要缺点是:
- 不能在它的循环体中使用 await。
- 不能提前退出 .forEach() 循环。而在 for 循环中可以使用 break。
中止 .forEach() 的解决方法
如果想要中止 .forEach() 之类的循环,有一种解决方法:.some() 还会循环遍历所有数组元素,并在其回调返回真值时停止。
const arr = ['red', 'green', 'blue']; arr.some((elem, index) => { if (index >= 2) { return true; // 中止循环 } console.log(elem); //此回调隐式返回 `undefined`,这 //是一个伪值。 因此,循环继续。 }); // Output: // 'red' // 'green'
可以说这是对 .some() 的滥用,与 for-of 和 break 比起来,要理解这段代码并不容易。
for of 的优点是可以使用await
如果有需要,可以轻松地迁移到 for-await-of。甚至可以将 break 和 continue 用于外部作用域。
for-of 和数组索引
数组方法 .entries() 返回一个可迭代的 [index,value] 对。如果使用 for-of 并使用此方法进行解构,可以很方便地访问数组索引:
const arr = ['chocolate', 'vanilla', 'strawberry']; for (const [index, elem] of arr.entries()) { console.log(index, elem); } // Output: // 0, 'chocolate' // 1, 'vanilla' // 2, 'strawberry'
总结:正常遍历数组统一都用for of,需要下标时可以用for (const [index, elem] of arr.entries())。
拓展:for await of 的使用场景(目前还没遇到过)
function getTime(seconds){ return new Promise(resolve=>{ setTimeout(() => { resolve(seconds) }, seconds); }) } async function test(){ let arr = [getTime(2000),getTime(300),getTime(1000)] for await (let x of arr){ console.log(x); // 2000 300 1000 按顺序的 } } test()
其他几种遍历方式
1. [...].some(ck)函数 某个一个为true,则为true
对数组中每个元素执行一次ck函数,直到某个元素返回true,则直接返回true。如果都返回false,则返回false
检查整个数组中是否有满足ck函数的元素。
//所有元素都不满足,返回result = false
var result = [1,5,3,6].some( (v,i) => (v>10) )
//有一个(多个)满足,返回result = true
2.[...].map(ck)函数 ---- 返回每个元素返回值的集合
每个数组元素都执行一次ck函数,最后返回每次元素执行ck函数后返回值的集合(数组)
//每个元素除以10,最后返回一个新数组 newArray = [5,3,4]
var newArray = [50,30,40].map( (v,i) => v/10 )
3.[...].filter(ck)函数,得到返回值为true的元素的集合
每个数组元素都执行一次ck函数,
最后返回每次元素执行ck函数后返回值的为true的元素集合(数组)
//返回数组中大于10的元素新数组 newArray = [50,60,53,15]
var newArray = [50,2,60,4,53,15].filter( (v,i) => (v>10) )
4.[...].find(ck)函数,得到第一个返回值为true的元素
和filter的用法差不多,区别就是返回true之后就不会再继续遍历了,
也就是不会再往后继续找了,并且返回的是元素本身,
而不是元素集合的数组,特殊场景下相比于filter可以节约性能。
和some的区别是,some返回的是true或者false。
find返回的是找到的元素本身或者undefined。
还有个findIndex方法,跟find用法一模一样,区别就是findIndex返回的是第一个ture的下标
5.[...].every(ck)函数 ---- 某一个为false,则返回false
每个数组元素都执行一次ck函数,直到某个元素执行函数ck返回false,则直接返回false,
如果全部返回true,则返回true
//返回有一个(多个)大于等于51,则返回 result = false
6.[...].reduce(ck,init) ---- 依次执行ck(prv.next)
数组依次执行ck函数。