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