在each()和forEach()中使用break和continue

时间:2015-06-24 02:55:38

标签: javascript

如果我们不能使用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;
     }
}
如果我不能使用中断或继续关键字,那么函数调用的优点是什么?

5 个答案:

答案 0 :(得分:6)

+--------+------+---------------------+---------------------+-----------------+ | userid | INS | OUTS | time_after_22pm_and_lessOrEqual6am | +--------+------+---------------------+---------------------+-----------------+ | 1 | 2015-06-25 15:00:00 | 2015-06-26 23:15:00| 01:15:00 | 2 | 2015-06-25 23:00:00 | 2015-06-26 13:30:00| 07:00:00 +--------+------+---------------------+---------------------+-----------------+ 2 rows in set .each()的灵活性低于普通.forEach()循环。他们就是。

正如您所发现的那样,它们可以减少对循环的控制。只有当你想迭代整个集合或它真正帮助你自动为你的循环迭代代码(有时在异步操作中有用)或者你喜欢使用更多的声明性编码时,它们才是一种便利。方法比for循环更清晰,更简洁地表达您的编码意图。 for也会自动跳过数组的稀疏元素。

除了这些功能之外,它们只是减少了输入,牺牲了一些循环控制。当您喜欢其中一个优点时使用它们,当您需要更多循环控制时,请不要使用它们。

仅供参考,对于Javascript数组,.forEach().some()会尝试让您恢复某些循环控制,但它们仍然不如.every()循环灵活。

如果您使用for,则.some()可以等同于return true;(因为这将停止循环),您只需break;即可return;(因为它将从回调返回并前进到下一次迭代)。

答案 1 :(得分:2)

说实话,没有太多的优势&#34;这很方便。您可以调用return强制自己退出forEach循环的单次迭代,但这与本机for不同,因为您仍在调用函数。方便的形式是不必定义循环的参数化(即起点,终点,步长)以及提供迭代项中索引和项的值。

值得一提的是,这种便利是以循环控制(即起点,终点,步长),向后迭代,break整个循环的能力,小的性能阻抗为代价的。 ,是的,甚至是跨浏览器合规性。

答案 2 :(得分:1)

each表达您的意图:为每个项目迭代并执行副作用。 each抽象迭代过程:初始化和递增计数器,按数组索引获取。这就是功能组合器所做的事情。

您的代码段就是一个很好的例子。让我们以函数式重写:

app.currentUser = collections.users.models.find(function (u) {
  return u.username === user.username;
});

find清楚地表达了你的意图并抽象出迭代的概念,直到找到与你的谓词匹配的项目。

答案 3 :(得分:1)

您无法原生地从forEacheach回调函数中断。但是,有一种技术可以让很多人用它来解决这个问题:

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对象,并在想要从不可破坏的循环中断时提升它。抓住特定的BreakException并继续执行你的功能。

要记住的一件事是,总是检查捕获的异常是否是您定义的BreakException ,因为其他可能的异常(如TypeError等)也被此catch语句捕获。不检查就不要吞下它。

答案 4 :(得分:0)

使用Array.prototype.someArray.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
});