js【最佳实践】遍历数组的八种方法(含数组遍历 API 的对比)for,forEach,for of,map,filter,reduce,every,some

遍历方法 返回值 使用场景 备注 副作用
for 循环 ------ 遍历数组 通用 可以改变原数组
forEach 循环 ------ 遍历数组 ES5 新增,不支持中断和异步 可以改变原数组
for of 循环 ------ 遍历数组 ES6 新增 可以改变原数组
map 格式化后的数组 格式化 数组的API 不会改变原数组
filter 过滤后的数组 过滤 数组的API 不会改变原数组
reduce 最终计算结果 累计 数组的API 不会改变原数组
every 匹配结果 全部匹配 数组的API 不会改变原数组
some 匹配结果 部分匹配 数组的API 不会改变原数组

for 循环

缺点:编码不太便捷

js 复制代码
for (let i = 0; i < arr.length; i++) {
    console.log(arr[i]);
}

forEach 循环

缺点:不支持中断和异步

js 复制代码
let arr = [1, 2, 3]

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

不支持中断

使用 return 提前结束当次循环,但还会继续遍历!

js 复制代码
let arr = [1, 2, 3]

arr.forEach((item) => {
  console.log(item)
  if (item === 2) {
    return
  }
  console.log('执行完本次循环')
})

打印结果

bash 复制代码
1
执行完本次循环
2
3
执行完本次循环

不支持异步

js 复制代码
import axios from 'axios'

let infoList = []

let id_list = ['1', '2', '3']

id_list.forEach(async (id) => {
  let res = await axios.get(`http://jsonplaceholder.typicode.com/users/${id}`)
  console.log(res)
  infoList.push(res.data)
})

console.log(infoList) // []

for of 循环【推荐】

默认只能遍历数组中的元素

js 复制代码
let arr = [1, 2, 3]

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

要获取到数组的下标,需使用 entries

js 复制代码
let arr = [1, 2, 3]

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

支持中断

使用 break 提前跳出循环(常用于遍历数组,查找目标元素)

js 复制代码
let arr = [1, 2, 3]

for (let item of arr) {
  console.log(item)
  if (item === 2) {
    break
  }
}
// 1 2

支持异步

js 复制代码
import axios from 'axios'

let infoList = []

let id_list = ['1', '2', '3']

async function getInfo(id_list, infoList) {
  for (let id of id_list) {
    let res = await axios.get(`http://jsonplaceholder.typicode.com/users/${id}`)

    infoList.push(res.data)
  }
  console.log(infoList) // 可得到预期结果
}

getInfo(id_list, infoList)

但更推荐使用 Promise.all 实现

js 复制代码
import axios from 'axios'

let infoList = []

let id_list = ['1', '2', '3']

let promise_list = []

for (let id of id_list) {
  promise_list.push(axios.get(`http://jsonplaceholder.typicode.com/users/${id}`))
}

Promise.all(promise_list).then((res) => {
  infoList = res.map((item) => item.data)
  console.log(infoList) // 可得到预期结果
})

map 格式化

js 复制代码
let arr = [
  {
    age: 20
  },
  {
    age: 30
  },
  {
    age: 40
  }
]

const result = arr.map((item) => {
  return {
    age: `${item.age}岁`
  }
})

console.log(result)
// [ { age: '20岁' }, { age: '30岁' }, { age: '40岁' } ]

filter 过滤

js 复制代码
let arr = [
  {
    name: '朝阳',
    age: 20
  },
  {
    name: '张三',
    age: 30
  },
  {
    name: '李四',
    age: 40
  }
]

const result = arr.filter(({ age }) => age < 30)

console.log(result)
//[ { name: '朝阳', age: 20 } ]

reduce 累计

如求和

js 复制代码
let arr = [1, 2, 3]
let sum = arr.reduce((lastResult, nextItem) => lastResult + nextItem)
console.log(sum) // 6

更多 reduce 高级用法见
https://blog.csdn.net/weixin_41192489/article/details/116661854

every 全部匹配

js 复制代码
let arr = [1, 2, 3]

// 是否每一个元素都小于 3
const result = arr.every((item) => item < 3)

console.log(result)
// false

some 部分匹配

js 复制代码
let arr = [1, 2, 3]

// 是否存在元素小于 3
const result = arr.some((item) => item < 3)

console.log(result)
// true
相关推荐
前端君5 小时前
实现最大异步并发执行队列
javascript
知识分享小能手6 小时前
React学习教程,从入门到精通,React 组件核心语法知识点详解(类组件体系)(19)
前端·javascript·vue.js·学习·react.js·react·anti-design-vue
蚂蚁RichLab前端团队7 小时前
🚀🚀🚀 RichLab - 花呗前端团队招贤纳士 - 【转岗/内推/社招】
前端·javascript·人工智能
萌萌哒草头将军7 小时前
Oxc 和 Rolldown Q4 更新计划速览!🚀🚀🚀
javascript·vue.js·vite
Qlittleboy8 小时前
uniapp如何使用本身的字体图标
javascript·vue.js·uni-app
林_深时见鹿8 小时前
Vue + ElementPlus 自定义指令控制输入框只可以输入数字
前端·javascript·vue.js
GDAL8 小时前
Knockout.js 任务调度模块详解
javascript·knockout
椒盐螺丝钉8 小时前
Vue组件化开发介绍
前端·javascript·vue.js
koooo~8 小时前
v-model与-sync的演变和融合
前端·javascript·vue.js
GW_Cheng8 小时前
分享一个vue2的tinymce配置
开发语言·javascript·ecmascript