首頁 >web前端 >js教程 >如何中斷forEach循環(詳細介紹)

如何中斷forEach循環(詳細介紹)

不言
不言轉載
2019-03-19 11:41:358661瀏覽

這篇文章帶給大家的內容是關於如何中斷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迴圈是不可以退出的。

引自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(&#39;a&#39;)
}
//不会造成死循环
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)。

這篇文章到這裡就已經全部結束了,更多其他精彩內容可以關注PHP中文網的

JavaScript教學影片專欄!

以上是如何中斷forEach循環(詳細介紹)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除