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
相关推荐
滿31 分钟前
Vue3 ElementPlus el-select 焦点事件数据不回显问题
javascript·vue.js·elementui
代码or搬砖32 分钟前
Vue生命周期总结(四个阶段,八个钩子函数)
前端·javascript·vue.js
梵尔纳多34 分钟前
第一个 Electron 程序
前端·javascript·electron
鹏北海-RemHusband34 分钟前
记录一次微前端改造:把 10+ 个独立 Vue 项目整合到一起
前端·javascript·vue.js
程序员小寒36 分钟前
前端高频面试题之Promise相关方法
前端·javascript·面试
阿蒙Amon39 分钟前
JavaScript学习笔记:8.日期和时间
javascript·笔记·学习
梵尔纳多41 分钟前
electron 安装
前端·javascript·electron
心.c1 小时前
初步了解Next.js
开发语言·前端·javascript·js
灵感__idea1 小时前
Hello 算法:以“快”著称的哈希
前端·javascript·算法