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

原文地址:https://www.cnblogs.com/smile-fanyin/p/14700539.html