如何在Array.forEach的循环里break
前段时间团队里讨论了一个问题,如何在forEach里实现break,目前有几种方案
throw法
抛出一个错误,但是需要注意的是要抛出一个可以与别的错误区别开的错误,这样不会干扰别的代码抛出的错误
var BreakException = {};
try {
    [1, 2, 3].forEach(function(v) {
        console.log(v); //只输出1,2
        if (v === 2) throw BreakException;
    });
} catch (e) {
    if (e !== BreakException) throw e;
}此法有点丑陋,加了不少代码
空跑循环
在外层加一个标识,如果此标识为true,接下来的循环空跑,码如下:
var breakFlag = false;
[1, 2, 3].forEach(function(v) {
    if (breakFlag === true) {
        return false;
    }
    if (v === 2) {
        breakFlag = true
    }
    console.log(v) //只输出1,2
})这个在外层加了一个变量,为了不污染外层的环境,我们可以使用forEach的第二个参数context,把标识放在这里
[1, 2, 3].forEach(function(v) {
    if (this.breakFlag === true) {
        return false;
    }
    if (v === 2) {
        this.breakFlag = true
    }
    console.log(v) //只输出1,2
}, {});这种方法不可避免的导致了不必要的运行,有点浪费cpu的感觉
神奇改数组大法
下面出场的这位选手,稍微有点技术含量
var array = [1, 2, 3, 4, 5];
array.forEach(function(item, index) {
    if (item === 2) {
        array = array.concat(array.splice(index, array.length - index));
    }
    console.log(item); //只输出1,2
});这种方法相当于改变了array,不知道大伙看出来了没有
最应该使用的every
前面啰嗦了这么多,真正的主角登场,最推荐的方式呢,就是这种需要break的场景下,直接使用every或者some吧
- every: 碰到return false的时候,循环中止
- some: 碰到return ture的时候,循环中止
两者的代码分别如下
var a = [1, 2, 3, 4, 5]
a.every(function(item, index, arry) {
    console.log(item); //返回1,2
    if (item === 2) {
        return false
    } else {
        return true
    }
})var a = [1, 2, 3, 4, 5]
a.some(function(item, index, arry) {
    console.log(item); //返回1,2
    if (item === 2) {
        return true
    } else {
        return false
    }
})当然如果你能使用forEach,却发现every没有,那么你可能需要es5-shim,forEach、every、some都是属于es5规范下的,这里有一个兼容列表
骚年用for吧
群里讨论的时候
目睹了这些的我也觉得有些认同。
部分参考
- http://stackoverflow.com/questions/2641347/how-to-short-circuit-array-foreach-like-calling-break
- http://old.doctyper.com/archives/200807/breaking-out-of-a-foreach-loop/
- https://coderwall.com/p/_ggh2w
- http://www.jsnoob.com/2013/11/26/how-to-break-the-foreach/
- http://stackoverflow.com/questions/6260756/how-to-stop-javascript-foreach