前言
记录一下JS中数组常用的循环方法。
forEach
forEach的使用频率可能在众多方法中位列第一,但是你真的了解它么?
使用语法: arr.forEach(callback(currentValue [, index [, array]])[, thisArg])
参数
- callback(当前处理的值,当前处理值下标,当前遍历的数组)
- this callback函数中的this指向
返回值
undefined
代码
let arr=[1,2,3,4,,6,null,undefined,''];
arr.forEach(console.log)
你会发现它不对未初始化的值进行操作,也就是4,,6中不会被遍历到。
let arr=[1,2,3,4,5];
arr.forEach((value,index,arr)=>{
arr.push(0);
console.log(value); // 1,2,3,4,5
})
console.log(arr); //[1,2,3,4,5,0,0,0,0,0]
可见遍历的范围是定义好的,也就是第一次执行回调函数时数组的值。调用forEach后添加到数组中的项不会被回调函数访问到。
let arr = [1, 2, 3, 4, 5];
arr.forEach((value, index, arr) => {
arr.unshift(0)
console.log(value); //1,1,1,1,1
})
console.log(arr); //[0, 0, 0, 0, 0, 1, 2, 3, 4, 5]
是不是感觉很矛盾?很打脸?让我慢慢给你分析。
虽然说范围是固定好了,但是还是可以挤出去的.
let arr = [1, 2, 3, 4, 5];
arr.forEach((value, index, arr) => {
if(index===2){
arr.splice(index,1)
}
console.log(value);//1,2,3,5
})
console.log(arr);//[1,2,4,5]
最后再说一点,forEach中的循环是不能用return终止的。如果你非要用,那也不是不可以。
let arr = [1, 2, 3, 4, 5];
try {
arr.forEach((value, index) => {
if (index === 2) {
throw new Error('终止')
}
console.log(value); //1,2
})
} catch ({ message }) {
console.log(message) //终止
}
map
map()方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。
用法:
使用语法: arr.map(callback(currentValue [, index [, array]])[, thisArg])
参数
- callback(当前处理的值,当前处理值下标,当前遍历的数组)
- this callback函数中的this指向 返回值
数组
let arr = [1, 2, 3, 4, 5, , 7, null, undefined];
let result = arr.map(value=>{
return value+''
})
console.table(result);//['1','2','3','4','5','7','null','undefined']
不对未初始化的值进行任何操作。
let arr = [1, 2, 3, 4, 5, , 7, null, undefined];
let result = arr.map(() => { })
console.table(result);//[undefined*9]
当callback函数没有返回值的时候,返回的数组长度与遍历数组长度一样且值都是undefined。
当在callback函数中改变数组时,操作结果与上述在forEach中一致。偷懒就不再写一遍了
filter
filter()方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素,简单说就是一个过滤的效果
用法
let newArray = arr.filter(callback(element[, index[, array]])[, thisArg])
参数
- callback(当前处理的值,当前处理值下标,当前遍历的数组)
- this callback函数中的this指向
返回值
数组
let arr = [0, 1, 2, 3, 4, 5];
let result = arr.filter(value => {
return value > 3
})
console.table(result); //[4,5]
在回调函数中过滤掉不符合要求的数据。
let arr = [0, 1, 2, 3, 4, 5];
let result = arr.filter(value => {
return 1; //返回一个‘真值’
})
console.table(result);//[0, 1, 2, 3, 4, 5]
filter为数组中的每个元素调用一次 callback函数,并利用所有使得 callback 返回 true 或等价于 true 的值的元素创建一个新数组。
同样,在callback函数中改变数组时,操作结果参考上述在forEach。偷懒就不再写一遍了
some
some()方法测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个Boolean类型的值。
用法
arr.some(callback(element[, index[, array]])[, thisArg] )
参数
- callback(当前处理的值,当前处理值下标,当前遍历的数组)
- this callback函数中的this指向
返回值
boolean(数组中有至少一个元素通过回调函数的测试就会返回true;所有元素都没有通过回调函数的测试返回值才会为false。)
let arr=[1,2,3,4,5];
let result=arr.some(function (value,index,arr) {
console.log(value);//1,2 [3,4,5]将不会在遍历
return value===2
})
console.table(result);//true
需要注意的是,当callback函数中发现第一个满足测试的值时,不管后续的值是否满足测试就会返回true。
let arr = []; //或则[,,,,]
let result = arr.some(function (value, index, arr) {
console.log(value);
return '真值'
})
console.table(result); //false
如果用一个空数组进行测试,在任何情况下它返回的都是false
let arr=[1,2,3,4,5];
let result=arr.some(function (value,index,arr) {
console.log(value); // 1
return '真值'
})
console.table(result);//true
some()为数组中的每一个元素执行一次 callback函数,直到找到一个使得 callback 返回一个“真值”。如果找到了这样一个值,some() 将会立即返回 true。否则,some()返回 false.
同样,在callback函数中改变数组时,操作结果参考上述在forEach。偷懒就不再写一遍了
every
every()方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。
用法
arr.every(callback(element[, index[, array]])[, thisArg])
参数
- callback(当前处理的值,当前处理值下标,当前遍历的数组)
- this callback函数中的this指向 返回值
boolean(如果回调函数的每一次返回都为'真值',返回 true ,否则返回 false。)
let arr = [1, 2, 3, 4, 5];
let result = arr.every(function (value, index, arr) {
return value>0
})
console.log(result);//true
let arr = [1, 2, 3, 4, 5];
let result = arr.every(function (value, index, arr) {
console.log(value); //1
return value > 2
})
console.log(result); //false
这里刚好和some方法的规则相反,在every中只要callback函数找到第一个不符合测试的值时,将直接返回false,后续的值不会再遍历。
let arr = [];
let result = arr.every(function (value, index, arr) {
console.log(value);//不执行
return false
})
console.log(result); //true
这里也和some方法的规则相反,用一个空数组进行测试,在任何情况下它返回的都是true。
find
find()方法返回数组中满足提供的测试函数的第一个元素的值。否则返回undefined。
用法
arr.find(callback[, thisArg])
参数
- callback(当前处理的值,当前处理值下标,当前遍历的数组)
- this callback函数中的this指向
返回值
数组中第一个满足所提供测试函数的元素的值,否则返回 undefined。
let arr=[1,2,3,4,5];
let result=arr.find((value,index,arr)=>{
console.log(value); //1
return value>0
})
console.log(result); //1
let arr=[1,2,3,4,5];
let result=arr.find((value,index,arr)=>{
console.log(value);//1,2,3,4,5
return value>6
})
console.log(result); //undefined
let arr = [, 2, , 4];
let result = arr.find((value, index, arr) => {
console.log(`index:${index}--value:${value}`);//index:0--value:undefined
return '真值'
})
console.log(result); //undefined
找到数组中第一个满足测试的值,并返回他。找到之后,后续的值将不会再遍历。要是数组中的值都不满足测试将返回undefined
let arr=[,2,,4]; //稀疏数组
let result=arr.find((value,index,arr)=>{
console.log(`index:${index}--value:${value}`);
})
console.log(result);
结果:
注意callback函数会为数组中的每个索引调用即从 0 到 length - 1,而不仅仅是那些被赋值的索引,这意味着对于稀疏数组来说,该方法的效率要低于那些只遍历有值的索引的方法。
还有一点再说一遍,find方法的返回值要么是数组中的值(从数组中找到第一个满足测试的值),要么就是undefined。
findIndex
findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1。
用法
arr.findIndex(callback[, thisArg])
参数
- callback(当前处理的值,当前处理值下标,当前遍历的数组)
- this callback函数中的this指向 返回值
数组中通过提供测试函数的第一个元素的索引。否则,返回-1。
let arr=[1,2,3,4,5];
let result=arr.findIndex((value,index,arr)=>{
console.log(value); //1,2
return value===2
})
console.log(result);//1
let arr=[1,2,3,4,5];
let result=arr.findIndex((value,index,arr)=>{
console.log(value);
return value===6
})
console.log(result);
在数组arr中找到第一个值为2的下标。当在数组中找到第一个满足测试的值后,就返回它的下标,后续数组中的值将不会遍历。都找不到就返回-1.
let arr=[1,2,3,4,5];
let result=arr.findIndex((value,index,arr)=>{
console.log(value);//1
return '真值'
})
console.log(result);// 0
需要注意的是,当callback函数的返回值为‘真值’,该方法就会结束,并将当前遍历的值的下标返回。
let arr = [1, , , 4, 5];
let result = arr.findIndex((value, index, arr) => {
console.log(value);//1,undefined*2,4,5
if (value == 5) {
return '真值'
}
})
console.log(result);// 4
该方法和find一样,callback函数会为数组中的每个索引调用即从 0 到 length - 1,而不仅仅是那些被赋值的索引,这意味着对于稀疏数组来说,该方法的效率要低于那些只遍历有值的索引的方法。