在使用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循环是不可以退出的。
引自MDN
There 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)
使用for...in遍历对象时,会遍历原型链上的可枚举属性,这可能会导致一些意想不到的问题。所以你一定收到过这样的建议,使用数组的forEach来代替for...in循环。本文给大家总结了5种在forEach中跳出循环的变通之法
在进行业务开发的过程中,使用了数组的高级函数map,同时使用了ES6语法async/await,发现在map循环下任务是异步执行的,并不符合预期。Array的循环方法map、forEach、filter、reduce、some、every等是并行迭代,可以理解为async/await的效果是无效的
如果您需要重复大量的代码数百次,这会变得非常笨拙。而且,它也不是很有用。例如,如果希望它重复X次呢?这就是循环的用武之地。次数通常由变量决定,但也可以由实际数字决定。
循环:就是一遍又一遍执行相同或者相似的代码,循环的两个要素:循环体:重复执行的代码;循环条件:控制循环的次数
创建一个新的数组,新的数组中的元素是通过检查指定数组中符合条件的元素;注意:1. filter()不会对空数组进行检测;2. filter()不会改变源是数组;
我在项目里面用到了的是全局守卫,beforeEach,方便管理 不过遇到了一个问题,就是在beforeEach()中设置好判断条件后出现了无限循环的问题 当时的代码如下:
对于本文中一些知识点任然有些模糊,懵懵懂懂,一直都在学习中,通过学习事件循环也看了一些文献,在其中看到了这一句话:除了你的代码,一切都是同步的,我觉得很有道理,对于理解事件循环很有帮助。
我们先来简单了解一下setTimeout延时器的运行机制。setTimeout会先将回调函数放到等待队列中,等待区域内其他主程序执行完毕后,按时间顺序先进先出执行回调函数。本质上是作用域的问题
for 常用于循环数组 ,for in 常用来循环对象,不建议循环数组,因为i是字符串 可能会有隐患问题,for in 循环会找到 prototype 上去,所以最好在循环体内加一个判断
我们经常会用到全局前置守卫,如判断用户有没有登陆过,如果登陆过就直接跳到目的页面,如果没有登陆过,就跳转到登陆页。先看官网对全局前置守卫的介绍
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!