js 的 forEach 循环中使用 return 不能跳出循环
N多年前使用 jquery 的时候,使用其 api 的 each 用法的时候,碰到过 return 不能跳出循环的问题,当时也没有记录,时间久了就忘记了,到现在只是隐隐约约的记得 jquery 的 each 和 js 的 forEach貌似有某种 bug,但是具体的真记不起来了。
现在的 vue 项目中,又碰到了在 forEach 中使用 return 的场景,故记录一下。
我们都知道 for 循环里要跳出整个循环是使用 break,但在数组中用 forEach 循环如要退出整个循环呢?使用 break 会报错,使用 return 也不能跳出循环。
使用 break 将会报错:
var arr=[1,2,3,4,5];
arr.forEach(function(val,i){
if(val==3){
break
}
console.log(val)
})
控制台结果为:
使用return也不能跳出整个循环:
var arr=[1,2,3,4,5];
arr.forEach(function(val,i){
if(val==3){
return // 这里使用 return false 也不行的
}
console.log(val)
})
控制台结果为:
看来 return 在 forEach 里面应该是充当了 continue 的角色。
那么在用 forEach() 遍历数组时要如何才能跳出循环呢?
第一种:使用 for 循环代替 forEach
在平时的项目中,我们大多数都是封装的函数,然后传参调用的。如下:
var arr=[1,2,3,4,5];
function fun(arr){
for(var i = 0; i<arr.length; i++){
if(arr[i]==3){
return
}
console.log(arr[i])
}
}
fun(arr);
控制台结果为:
直接使用 for 的话,只能用 break,不能使用 return,因为 return 是针对函数使用的,如下:
var arr=[1,2,3,4,5];
for(var i = 0; i<arr.length; i++){
if(arr[i]==3){
break
}
console.log(arr[i])
}
控制台结果为:
第二种:使用try···catch捕获异常实现 (不建议使用,个人感觉麻烦)
try{
var arr=[1,2,3,4,5];
arr.forEach(function(val,i){
if(val == 3){
throw new Error("ending"); //抛出错误
}else{
console.log(val);
}
})
}catch(e){
//其实 catch 中的代码全部注释掉不要都可以
if(e.message == "ending"){
console.log("结束了") ;
}
}
//不影响下面代码的执行
console.log(10);
控制台结果为:
第三种:使用arr.some()或者arr.every()替代(注意里面 return 的返回值)
some()当内部 return true 时跳出整个循环:
var arr=[1,2,3,4,5];
arr.some(function(val,i){
if(val==3){
//注意这里不能是return或者return false,一般写return true(写return 1 也行,意思一样)
return true;
}
console.log(val)
})
every()当内部 return false 时跳出整个循环(注意写法,有点特别)
var arr=[1,2,3,4,5];
arr.every(function(val,i){
if(val==3){
return false; //注意这里是return false
}else{
console.log(val);
return true; //注意这里的 return true 必须加上,不然会异常(打印不出2)
}
})
控制台结果为:
如果代码为:
var arr=[1,2,3,4,5];
arr.every(function(val,i){
if(val==3){
return false;
}
console.log(val)
})
那么控制台的打印结果为:
是不是很诡异?竟然没有打印出来2!
加上 return true 之后:
arr.every(function(val,i){
if(val==3){
return false;
}
console.log(val);
return true;
})
控制台结果:
此时打印结果才正常。(所以为了代码美观,把后面的 console.log(val); return true; 放到了 else 里面)
总结:
1、try···catch不好用,麻烦。
2、some 和 every 的方法,里面的 return 后面还必须跟 false 或者 true(至于返回 true 还是 false,时间久了估计就忘了),其中 every 还有坑。
3、个人感觉还是在函数体内部用for循环吧,通过 return 终止,简单便捷,还容易记。
番外篇:
同理,jquery 中的 each 循环也会存在 return 不能终止循环的问题。具体可见:
https://www.cnblogs.com/smile-fanyin/p/14700581.html