JS常用的循环遍历和它们的特性
2021年6月10日
14分钟阅读
7 次浏览
0 条评论
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
-
for
通常用于数组的循环 可以随时跳出循环,用 break 或者 continue
js1const 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}
-
forEach
可以对循环的元素做一些特定的操作,回调函数的参数更丰富,元素,索引和原数组都可以获得。
forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。
注意: forEach() 对于空数组是不会执行回调函数的。
回调函数的语法如下:
array.forEach(function(currentValue, index, arr), thisValue)
其中 第一个参数为回调函数
function(currentValue, index, arr)
,currentValue 是必须的,表示当前的正在遍历的元素,index 和 arr 是可选的,分别表示当前元素的索引以及当前元素所属的数组对象第二个参数 thisValue 是可选的,传递给函数的值一般用
this
值,如果这个参数为空,undefined
,会传递给this
值js1const 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 代替。
js1var 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
js1const list = [1, 2, 3, 4] 2const result = list.forEach(function(cur) { 3 return cur 4}) 5console.log(result) //undefined
-
for in
-
获取 enumerable:true 的属性键。
-
可以遍历对象(这时候获得是对象的键)和数组(数组的索引)。
-
可以获取原型上的属性键。
-
数字属性键被遍历出来是字符串。比如索引值
-
不可以跳出循环
js1const 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)
后者将会创建一个全局变量。遍历的顺序会因为浏览器的不同而不同
-
-
for of:
-
遍历属性值。不受到 enumerable 限制。
-
可遍历数组。一般不可以遍历对象,如果实现了 Symbol.iterator,可以遍历。如 Array,Map,Set,String,TypedArray,arguments 对象等等
-
不能获取原型上的值
-
可以用 break 退出循环和 continue 跳过循环
-
for ...of 直接访问的是实际元素
-
如果遇到空元素同样会执行
js1const 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
-
some() 方法用于检测数组中的元素是否满足指定条件(函数提供)。
some() 方法会依次执行数组的每个元素:
- 如果有一个元素满足条件,则表达式返回true ,
剩余的元素不会再执行检测
。 - 如果没有满足条件的元素,则返回 false。
注意:
some() 不会对空数组进行检测
。注意:
some() 不会改变原始数组
。some 语法:
array.some(function(currentValue,index,arr),thisValue)
和 forEach 类似
注意:
返回值: 布尔值。如果数组中有元素满足条件返回 true,否则返回 false。
js1const 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
- 如果有一个元素满足条件,则表达式返回true ,
-
every
every() 方法用于检测数组所有元素是否都符合指定条件(通过函数提供)。
every() 方法使用指定函数检测数组中的所有元素:
- 如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。
- 如果所有元素都满足条件,则返回 true。
注意:
every() 不会对空数组进行检测
。注意:
every() 不会改变原始数组
。返回值:布尔值。如果所有元素都通过检测返回 true,否则返回 false。
js1const 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
-
filter
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
注意: filter() 不会对空数组进行检测。
注意: filter() 不会改变原始数组。
语法:
array.filter(function(currentValue,index,arr), thisValue)
与 forEach 类似返回值:返回数组,包含了符合条件的所有元素。如果没有符合条件的元素则返回空数组。
-
map
map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
map() 方法按照原始数组元素顺序依次处理元素。
注意: map() 不会对空数组进行检测。
注意: map() 不会改变原始数组。
语法:
array.map(function(currentValue,index,arr), thisValue)
返回值:返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
比较:
- 二者都是生成一个新数组,都不会改变原数组(不包括遍历对象数组时,在回调函数中操作元素对象)。
- 二者都会跳过空元素。
- map 会将回调函数的返回值组成一个新数组,
数组长度与原数组一致
。 - filter 会将符合回调函数条件的元素组成一个新数组。
- map 生成的新数组元素可自定义。
- filter 生成的新数组元素不可自定义,与对应原数组元素一致。
js1const 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
-
find
find() 方法返回通过测试(函数内判断)的数组的第一个元素的值。
find() 方法为数组中的每个元素都调用一次函数执行:
- 当数组中的元素在测试条件时返回 true 时, find() 返回符合条件的元素,
之后的值不会再调用执行函数。
(找到就停止) - 如果没有符合条件的元素返回 undefined
注意: find() 对于空数组,函数是不会执行的。
注意: find() 并没有改变数组的原始值。
语法:
array.find(function(currentValue, index, arr),thisValue)
返回值:返回符合测试条件的第一个数组元素值,如果没有符合条件的则返回 undefined。
- 当数组中的元素在测试条件时返回 true 时, find() 返回符合条件的元素,
-
findIndex() 方法返回传入一个测试条件(函数)符合条件的数组第一个元素位置。
findIndex() 方法为数组中的每个元素都调用一次函数执行:
- 当数组中的元素在测试条件时返回 true 时, findIndex() 返回符合条件的元素的索引位置,之后的值不会再调用执行函数。
- 如果没有符合条件的元素返回 -1
注意: findIndex() 对于空数组,函数是不会执行的。
注意: findIndex() 并没有改变数组的原始值。
语法:
array.findIndex(function(currentValue, index, arr), thisValue)
返回值:返回符合测试条件的第一个数组元素
索引
,如果没有符合条件的则返回 -1。
js1const 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() 对于空数组
是不会执行回调函数的。
js1const 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
参考文章
喜欢这篇文章吗?
加载中...
评论
0 条登录后即可参与评论讨论
加载评论中...
相关文章
目录