乐趣区

如何中断forEach循环

课程视频 – 如何中断 forEach 循环
在使用 for 循环的时候可以使用 break 或者 return 语句来结束 for 循环(return 直接结束函数),但是如果使用 forEach 循环如何跳出循环呢?
尝试使用 break 和 return
首先尝试一使用 return 语句 —- 木有效果
[1,2,3,4,5].forEach(item=>{
if(item===2){
return
}
console.log(item);
})
MDN 给出的官方解释
为什么会出现这样的情况?先看一下官方文档的说明。MDN 文档上明确说明 forEach 循环是不可以退出的。
引自 MDNThere is no way to stop or break a forEach() loop other than by throwing an exception. If you need such behavior, the forEach() method is the wrong tool. 注意:没有办法中止或者跳出 forEach() 循环,除了抛出一个异常。如果你需要这样,使用 forEach() 方法是错误的。若你需要提前终止循环,你可以使用:简单循环 for…of 循环 Array.prototype.every()Array.prototype.some()Array.prototype.find()Array.prototype.findIndex()
探究为什么 break 和 return 不行
先看看为什么 return 没有效果,break 报错,forEach 的实现方式用代码表示出来可以写成如下的结构
const arr = [1, 2, 3, 4, 5];
for (let i = 0; i < arr.length; i++) {
const rs = (function(item) {
console.log(item);
if (item > 2) return false;
})(arr[i])
}

使用 return 语句相当于在每个自执行函数中将返回值复制给 rs,但是实际对整个函数并没有影响。而使用 break 语句报错是因为再 JS 的解释器中 break 语句是不可以出现在函数体内的。
如何变通跳出 forEach 循环
MDN 官方推荐的方法
// every 在碰到 return false 的时候,中止循环。some 在碰到 return ture 的时候,中止循环。
var a = [1, 2, 3, 4, 5]
a.every(item=>{
console.log(item); // 输出:1,2
if (item === 2) {
return false
} else {
return true
}
})
var a = [1, 2, 3, 4, 5]
a.some(item=> {
console.log(item); // 输出:1,2
if (item === 2) {
return true
} else {
return false
}
})
其他方法
1. 使用 for 循环或者 for in 循环代替
2. 使用 throw 抛出异常
try {
[1, 2, 3, 4, 5].forEach(function(item) {
if (item=== 2) throw item;
console.log(item);
});
} catch (e) {}
3. 使用判断跑空循环
var tag;
[1, 2, 3, 4, 5].forEach(function(item){
if(!tag){
console.log(item);
if(item===2){
tag=true;
}
}
这样做有两个问题,第一个问题,全局增加了一个 tag 变量,第二个问题,表面上看是终止了 forEach 循环,但是实际上循环的次数并没有改变,只是在不满足条件的时候 callback 什么都没执行而已,先来解决第一个问题,如何删除全局下新增的 tag 变量。实际上 forEach 还有第二个参数,表示 callback 的执行上下文,也就是在 callback 里面 this 对应的值。因此我们可以讲上下文设置成空对象,这个对象自然没有 tag 属性,因此访问 this.tag 的时候会得到 undefined
[1, 2, 3, 4, 5].forEach(function(item){
if(!this.tag){
console.log(item);
if(item===2){
this.tag=true;
}
}
},{})
4. 修改索引
var array=[1, 2, 3, 4, 5]
array.forEach(item=>{
if (item == 2) {
array = array.splice(0);
}
console.log(item);
})
讲解:
forEach 的执行细节
1. 遍历的范围在第一次执行 callback 的时候就已经确定,所以在执行过程中去 push 内容,并不会影响遍历的次数,这和 for 循环有很大区别,下面的两个案例一个会造成死循环一个不会
var arr=[1,2,3,4,5]
// 会造成死循环的代码
for(var i=0;i<arr.length;i++){
arr.push(‘a’)
}
// 不会造成死循环
arr.forEach(item=>arr.push(‘a’))
2. 如果已经存在的值被改变,则传递给 callback 的值是 forEach 遍历到他们那一刻的值。
var arr=[1,2,3,4,5];
arr.forEach((item,index)=>{
console.log(`time ${index}`)
arr[index+1]=`${index}a`;
console.log(item)
})

3. 已删除的项不会被遍历到。如果已访问的元素在迭代时被删除了(例如使用 shift()),之后的元素将被跳过。
var arr=[1,2,3,4,5];
arr.forEach((item,index)=>{
console.log(item)
if(item===2){
arr.length=index;
}
})
在满足条件的时候将后面的值截掉,下次循环的时候照不到对应的值,循环就结束了,但是这样操作会破坏原始的数据,因此我们可以使用一个小技巧,即将数组从 0 开始截断,然后重新赋值给数组也就是 array=array.splice(0)

原始高清视频下载
视频讲解 – 提取码: 558x
我们的链接:
知乎 掘金 今日头条 新浪微博 前端网 思否 简书 B 站

退出移动版