課程目錄
1.嘗試使用break 和return
2.MDN給出的官方解釋
3.探究為什麼break和return不行
4.如何變通跳出forEach迴圈
5.關於我們
嘗試使用break 和return
1. 首先嚐試一使用return語句----木有效果
[1,2,3,4,5].forEach(item=>{
if(item===2){
return
}
console.log(item);
})
複製程式碼
2. 在嘗試一下使用break語句----報錯
[1,2,3,4,5].forEach(item=>{
if(item===2){
break
}
console.log(item);
})
複製程式碼
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不行
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迴圈
1.使用 some 和 every
// 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
}
})
複製程式碼
2.其他方法
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);
})
複製程式碼
5) forEach的執行細節:
遍歷的範圍在第一次執行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'))
複製程式碼
如果已經存在的值被改變,則傳遞給 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)
})
複製程式碼
已刪除的項不會被遍歷到。如果已訪問的元素在迭代時被刪除了(例如使用 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)
關於我們
視訊課程線上觀看-----傳送門
視訊課程網盤地址-----傳送門 提取碼: 558x
冰山社團官網地址-----傳送門
如果觀看視訊或文件後,你覺得有些收穫,願意加入冰山社團與我們一同成長,請進入我們的官網,點選冰山社團,加入我們~