[英]Using break and continue in each() and forEach()
如果我們不能使用break和continue關鍵字,我不確定我是否理解函數式循環/映射的價值。
我可以做這個:
collections.users.models.forEach(function(item, index) {
//can't use break or continue...?
});
或者我可以這樣做:
for (var i = 0; i < collections.users.models.length; i++) {
if (user.username === collections.users.models[i].username) {
app.currentUser = collections.users.models[i];
break;
}
}
如果我不能使用break或continue關鍵字,那么函數調用的優點是什么?
.each()
或.forEach()
不如普通for
循環靈活。 他們就是。
正如您所發現的那樣,它們可以減少對循環的控制。 只有當你想要迭代整個集合或它真正幫助你自動為你的循環迭代代碼(有時在異步操作中有用)或者你喜歡使用更多的聲明性編碼時,它們才是方便的。方法比for
循環更清晰,更簡潔地表達您的編碼意圖。 .forEach()
還將自動跳過數組的稀疏元素。
除了這些功能之外,它們只是減少了輸入,犧牲了一些循環控制。 當您喜歡其中一個優點時使用它們,並在需要更多循環控制時不使用它們。
僅供參考,對於Javascript數組, .some()
和.every()
嘗試讓您返回一些循環控件,盡管它們仍然不像for
循環那樣靈活。
如果你使用.some()
,你可以return true;
相當於break;
(因為這將停止循環)你可以return;
相當於continue;
(因為那將從回調返回並前進到下一次迭代)。
說實話,沒有太多的“優勢”,只有方便。 您可以調用return
以強制自己退出forEach
循環的單個迭代,但這與本機不同for
因為您仍在調用函數。 方便的形式是不必定義循環的參數化(即起點,終點,步長)以及提供迭代項中索引和項的值。
值得一提的是,這種便利是以循環控制(即起點,終點,步長),向后迭代, break
整個循環的能力,小的性能阻抗為代價的,甚至是跨瀏覽器合規性。
each
表達你的意圖:迭代並為每個項目執行副作用。 each
抽象迭代過程:初始化和遞增計數器,按數組索引獲取。 這就是功能組合器所做的。
您的代碼段就是一個很好的例子。 讓我們以函數式重寫:
app.currentUser = collections.users.models.find(function (u) {
return u.username === user.username;
});
find
清楚地表達您的意圖並抽象迭代的概念,直到找到與您的謂詞匹配的項目。
你不能本身打破forEach
或each
回調函數。 但是,有一種技術很多人用它來定制異常:
var BreakException = function(){};
try{
list.forEach(function(el){
if (meetCriteria(el)){
throw BreakException; // Break from forEach
}
});
}
catch (e){
// Catch break
if (e != BreakException)
throw e; // If not a break, but other exceptions, raise it
}
// Carry on
上面的簡單方法是創建一個BreakException
對象,並在想要從unbreakable循環中斷時提升它。 捕獲特定的BreakException
並繼續執行您的函數。
要記住的一件事是, 總是檢查捕獲的異常是否是您定義的BreakException ,因為其他可能的異常(如TypeError等)也被此catch語句捕獲。 不檢查就不要吞下它。
使用Array.prototype.some
和Array.prototype.every
繼續/打破功能for循環是一件好事
[1,2,3,null,5].every(function(v){
if(!v) return false; // this will break out of the loop
// do your regular loopage lulz
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.