igCircle Blog

JS常用的循环遍历和它们的特性

2021年6月10日

14分钟阅读

5 次浏览

0 条评论

前端三大件

标签

js

JS 常用的循环遍历 for、forEach、for ...of for…in 1. for 通常用于数组的循环 可以随时跳出循环,用 break 或者 continue `js const list = [1, 2, 3, 4, 5, 6, 7, 8, , 10, 11] let len = list.length for (let i = 0; i < l...

JS 常用的循环遍历

for、forEach、for ...of for…in

  1. for

    通常用于数组的循环 可以随时跳出循环,用 break 或者 continue

    js
    1const list = [1, 2, 3, 4, 5, 6, 7, 8, , 10, 11]
    2let len = list.length
    3for (let i = 0; i < len; i++) {
    4 if (list[i] === 5) {
    5  //   break; // 1 2 3 4
    6  continue // 1 2 3 4 6 7 8 undefined 10 11
    7 }
    8 console.log(list[i])
    9}
  2. forEach

    可以对循环的元素做一些特定的操作,回调函数的参数更丰富,元素,索引和原数组都可以获得。

    forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。

    注意: forEach() 对于空数组是不会执行回调函数的。

    回调函数的语法如下:

    array.forEach(function(currentValue, index, arr), thisValue)

    其中 第一个参数为回调函数function(currentValue, index, arr) ,currentValue 是必须的,表示当前的正在遍历的元素,index 和 arr 是可选的,分别表示当前元素的索引以及当前元素所属的数组对象

    第二个参数 thisValue 是可选的,传递给函数的值一般用this值,如果这个参数为空,undefined,会传递给this

    js
    1const list = [1, 2, 3, 4, 5, 6, 7, 8, , 10, 11]
    2let len = list.length
    3let result = []
    4list.forEach(function(cur, index, arr) {
    5 console.log(`当前元素为${cur},索引为${index},所属数组为${arr}`)
    6 result.push(cur * 2)
    7})
    8
    9console.log(result) //[ 2,  4,  6,  8, 10, 12, 14, 16, 20, 22]
    10
    11let rest = []
    12rest.forEach(function(cur) {
    13 console.log('我没有执行啊~~,因为我是空数组')
    14})

    注意:forEach 无法跳出循环,一旦执行了,除非抛出错误,否则会一直执行下去,直到数组的最后一个元素。

    不支持 continue,用 return false 或 return true 代替。

    js
    1var arr = [1, 2, 3, 4, 5]
    2arr.forEach(function(item) {
    3 if (item === 3) {
    4  return
    5 }
    6 console.log(item) //1 2 4 5
    7})

    不支持 break,用 try catch/every/some 代替:

    返回值: undefined

    js
    1const list = [1, 2, 3, 4]
    2const result = list.forEach(function(cur) {
    3 return cur
    4})
    5console.log(result) //undefined
  1. for in

    1. 获取 enumerable:true 的属性键。

    2. 可以遍历对象(这时候获得是对象的键)和数组(数组的索引)。

    3. 可以获取原型上的属性键。

    4. 数字属性键被遍历出来是字符串。比如索引值

    5. 不可以跳出循环

    js
    1const list = [1, 2, 3, 4, 5, 6, 7, 8, , 10, 11]
    2let len = list.length
    3
    4//1. 对于数组
    5for (const k in list) {
    6 // console.log(k); //[0,1,2,3,4,5,6,7,8,9,10]  //k 是索引
    7 console.log(list[k]) //[1,2,3,4,5,6,7,8,10,11] //忽略空元素
    8 if (k === 5) {
    9  //不会退出
    10  break
    11 }
    12}
    13
    14Object.prototype.fun = () => {}
    15const obj = { 2: 'a', 1: 'b' }
    16for (const i in obj) {
    17 console.log(i, ':', obj[i])
    18}
    19// 1: b
    20// 2: a
    21// fun : () => {} Object 原型链上扩展的方法也被遍历出来
    22
    23for (const i in obj) {
    24 if (Object.prototype.hasOwnProperty.call(obj, i)) {
    25  console.log(i, ':', obj[i])
    26 }
    27}
    28
    29//1 : b
    30//2 : a
    31
    32// fun不属于自身的属性将被 hasOwnProperty 过滤

    注意:

    使用 for in 循环时,返回的是所有能够通过对象访问的、可枚举的属性,既包括存在于实例中的属性,也包括存在于原型中的实例。如果只需要获取对象的实例属性,可以使用 hasOwnProperty 进行过滤

    使用时,要使用 (const x in a) 而不是 (x in a) 后者将会创建一个全局变量。

    遍历的顺序会因为浏览器的不同而不同

  2. for of:

    1. 遍历属性值。不受到 enumerable 限制。

    2. 可遍历数组。一般不可以遍历对象,如果实现了 Symbol.iterator,可以遍历。如 Array,Map,Set,String,TypedArray,arguments 对象等等

    3. 不能获取原型上的值

    4. 可以用 break 退出循环和 continue 跳过循环

    5. for ...of 直接访问的是实际元素

    6. 如果遇到空元素同样会执行

    js
    1const list = [1, 2, 3, 4, 5, 6, 7, 8, , 10, 11]
    2let len = list.length
    3
    4//1. 对于数组
    5for (const v of list) {
    6 //  console.log(v); //[1,2,3,4,5,6,7,8,undefined,10,11]  //v 是元素的值  不会忽略空元素
    7 if (v === 7) break //允许退出  continue也有有效
    8 console.log(v) //[1,2,3,4,5,6]
    9}
    10
    11// 2 对于对象
    12// 原型上增加方法
    13Array.prototype.gogo = function() {
    14 console.log('gogo')
    15}
    16
    17var a = [1, 2, 3]
    18
    19// key值2不可以枚举
    20Object.defineProperty(a, 2, {
    21 enumerable: false,
    22})
    23Object.defineProperty(a, '2', {
    24 enumerable: false,
    25})
    26
    27for (let p in a) {
    28 // 索引被遍历出来是字符串类型
    29 console.log(p, typeof p) // 0 string; 1 string; gogo string
    30}
    31
    32console.log('---')
    33
    34for (let v of a) {
    35 console.log(v) // 1 2 3
    36}

some every

  1. some() 方法用于检测数组中的元素是否满足指定条件(函数提供)。

    some() 方法会依次执行数组的每个元素:

    • 如果有一个元素满足条件,则表达式返回true ,剩余的元素不会再执行检测
    • 如果没有满足条件的元素,则返回 false。

    注意some() 不会对空数组进行检测

    注意some() 不会改变原始数组

    some 语法:

    array.some(function(currentValue,index,arr),thisValue)

    和 forEach 类似

    注意:

    返回值: 布尔值。如果数组中有元素满足条件返回 true,否则返回 false。

    js
    1const list = [
    2 { name: '头部导航', backward: false },
    3 { name: '轮播', backward: true },
    4 { name: '页脚', backward: false },
    5]
    6const someBackward = list.some((item) => item.backward)
    7console.log(someBackward) //true
    8
    9const arr = [1, 2, 3, 4]
    10const result = arr.some(function(item) {
    11 if (item === 5) return true
    12})
    13
    14console.log(result) //false
  2. every

    every() 方法用于检测数组所有元素是否都符合指定条件(通过函数提供)。

    every() 方法使用指定函数检测数组中的所有元素:

    • 如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。
    • 如果所有元素都满足条件,则返回 true。

    注意every() 不会对空数组进行检测

    注意every() 不会改变原始数组

    返回值:布尔值。如果所有元素都通过检测返回 true,否则返回 false。

js
1const list = [
2 { name: '头部导航', backward: false },
3 { name: '轮播', backward: true },
4 { name: '页脚', backward: false },
5]
6
7const everyNewest = list.every((item) => !item.backward)
8console.log(everyNewest) //false
9
10const arr = [1, 2, 3, 4]
11const result = arr.every(function(item) {
12 if (item > 3) return true
13})
14console.log(result) //false
15
16const result2 = arr.every(function(item) {
17 if (item < 5) return true
18})
19console.log(result2) //true

比较

  • 二者都是用来做数组条件判断的,都是返回一个布尔值。
  • 二者都可以被中断。
  • some 若某一元素满足条件,返回 true,循环中断。所有元素不满足条件,返回 false。
  • every 与 some 相反,若有一元素不满足条件,返回 false,循环中断。所有元素满足条件,返回 true。

filter、map

  1. filter

    filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。

    注意: filter() 不会对空数组进行检测。

    注意: filter() 不会改变原始数组。

    语法:array.filter(function(currentValue,index,arr), thisValue) 与 forEach 类似

    返回值:返回数组,包含了符合条件的所有元素。如果没有符合条件的元素则返回空数组。

  2. map

    map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。

    map() 方法按照原始数组元素顺序依次处理元素。

    注意: map() 不会对空数组进行检测。

    注意: map() 不会改变原始数组。

    语法:array.map(function(currentValue,index,arr), thisValue)

    返回值:返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。

比较:

  • 二者都是生成一个新数组,都不会改变原数组(不包括遍历对象数组时,在回调函数中操作元素对象)。
  • 二者都会跳过空元素。
  • map 会将回调函数的返回值组成一个新数组,数组长度与原数组一致
  • filter 会将符合回调函数条件的元素组成一个新数组。
  • map 生成的新数组元素可自定义。
  • filter 生成的新数组元素不可自定义,与对应原数组元素一致。
js
1const list = [
2 { name: '头部导航', type: 'nav', id: 1 },
3 ,
4 { name: '轮播', type: 'content', id: 2 },
5 { name: '页脚', type: 'nav', id: 3 },
6]
7const resultList = list.filter((item) => {
8 return item.type === 'nav'
9})
10console.log(resultList) //跳过空元素
11//输出:
12//[
13//   { name: '头部导航', type: 'nav', id: 1 },
14//   { name: '页脚', type: 'nav', id: 3 },
15// ]
16
17const newList = list.map((item) => {
18 console.log(item)
19 return item.id
20})
21console.log(newList) //[1, , 2, 3] //跳过空元素

find、findIndex

  1. find

    find() 方法返回通过测试(函数内判断)的数组的第一个元素的值。

    find() 方法为数组中的每个元素都调用一次函数执行:

    • 当数组中的元素在测试条件时返回 true 时, find() 返回符合条件的元素,之后的值不会再调用执行函数。(找到就停止)
    • 如果没有符合条件的元素返回 undefined

    注意: find() 对于空数组,函数是不会执行的。

    注意: find() 并没有改变数组的原始值。

    语法:array.find(function(currentValue, index, arr),thisValue)

    返回值:返回符合测试条件的第一个数组元素值,如果没有符合条件的则返回 undefined

  2. findIndex() 方法返回传入一个测试条件(函数)符合条件的数组第一个元素位置。

    findIndex() 方法为数组中的每个元素都调用一次函数执行:

    • 当数组中的元素在测试条件时返回 true 时, findIndex() 返回符合条件的元素的索引位置,之后的值不会再调用执行函数。
    • 如果没有符合条件的元素返回 -1

    注意: findIndex() 对于空数组,函数是不会执行的。

    注意: findIndex() 并没有改变数组的原始值。

    语法:array.findIndex(function(currentValue, index, arr), thisValue)

    返回值:返回符合测试条件的第一个数组元素索引,如果没有符合条件的则返回 -1。

js
1const list = [
2 { name: '头部导航', id: 1 },
3 { name: '轮播', id: 2 },
4 { name: '页脚', id: 3 },
5]
6const result = list.find((item) => item.id === 3)
7// result: { name: '页脚', id: 3 }
8const index = list.findIndex((item) => item.id === 3)
9// index: 2

小结

  • 二者都是用来查找数组元素。
  • find 方法返回数组中满足 callback 函数的第一个元素的值。如果不存在返回 undefined。
  • findIndex 它返回数组中找到的元素的索引,而不是其值,如果不存在返回 -1。

reduce、reduceRight

reduce 方法接收两个参数,第一个参数是回调函数(callback)【必须】 ,第二个参数是初始值(initialValue)【可选】。

reduceRight 方法除了与 reduce 执行方向相反外(从右往左),其他完全与其一致。

array.reduce(function(total, current, currentIndex, sourceArray), initialValue)

回调函数接收四个参数:

  • total:MDN 上解释为累计器,可以理解为它应该是截至当前元素,之前所有的数组元素被回调函数处理累计的结果。
  • current:当前被执行的数组元素。
  • currentIndex: 当前被执行的数组元素索引。
  • sourceArray:原数组,也就是调用 reduce 方法的数组。

initialValue 可选。传递给函数的初始值

如果不传入初始值,reduce 方法会从索引 1 开始执行回调函数,如果传入初始值,将从索引 0 开始、并从初始值的基础上累计执行回调。

返回值: 返回计算结果

注意: reduce() 对于空数组是不会执行回调函数的。

js
1const list = [
2 { name: 'left', width: 20 },
3 { name: 'center', width: 70 },
4 { name: 'right', width: 10 },
5]
6const total = list.reduce((currentTotal, item) => {
7 return currentTotal + item.width
8}, 0)
9// total: 100

参考文章

JS 常用的循环遍历你会几种

喜欢这篇文章吗?

加载中...

评论

0

登录后即可参与评论讨论

加载评论中...

相关文章

call bind apply的区别以及源码的手写

call方法的第一个参数也是this的指向,后面传入的是一个参数列表改变this指向后原函数会立即执行,且此方法只是临时改变this指向一次 当第一个参数为null、undefined的时候,默认指向window(在浏览器中) `js function fn(...args) { console.log(this的指向为${this}, args) } let obj = { ...

前端三大件
js手写

2025-08-06

2

0

目录

JS常用的循环遍历和它们的特性 - igCircle Blog