Javascript 在each()和forEach()中使用break和continue
如果我们不能使用break和continue关键字,我不确定我是否理解函数式循环/映射的价值 我可以这样做:Javascript 在each()和forEach()中使用break和continue,javascript,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 === colle
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;
}
}
或者我可以这样做:
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;
}
}
for(var i=0;i
如果我不能使用break或continue关键字,函数调用有什么好处?老实说,除了方便之外,没有什么“好处”。您可以调用
return
强制自己退出forEach
循环的单个迭代,但这与的本机不同,因为您仍在调用函数。方便的形式是不必定义循环的参数化(即起点、终点、步长)以及在迭代的项中提供索引和项的值
值得一提的是,这种便利性是以for循环控制(即起点、终点、步长)、向后迭代、中断整个循环的能力、较小的性能阻抗,甚至跨浏览器遵从性为代价的。.each()
或.forEach()
的灵活性不如普通的循环。他们就是这样
正如您所发现的,它们对循环的控制较少。只有当您想要迭代整个集合,或者当它真正帮助您为循环迭代代码自动创建新的函数上下文时(有时在异步操作中有用),它们才是一种方便或者当您喜欢更具声明性的编码时,使用该方法比for
循环更清楚、简洁地表达您的编码意图.forEach()
还将自动跳过数组的稀疏元素
除了这些特性之外,它们只是减少了输入,牺牲了一些循环控制。当您喜欢其中一个优点时使用它们,当您需要更多的循环控制时不要使用它们
仅供参考,对于Javascript数组,.some()
和.every()
试图让您返回一些循环控制,尽管它们仍然不如for
循环灵活
如果使用.some()
,则可以返回true代码>相当于中断代码>(因为这将停止循环),您只需返回代码>相当于continue代码>(因为它将从回调返回并前进到下一次迭代)。每个
都表达了您的意图:对每个项目进行迭代并执行副作用each
抽象了迭代过程:初始化并递增计数器,按数组索引获取。这就是函数组合子所做的
您的代码片段就是一个很好的例子。让我们以功能性的方式重写它:
app.currentUser = collections.users.models.find(function (u) {
return u.username === user.username;
});
find
清楚地表达了您的意图,并抽象了迭代的概念,直到您找到与谓词匹配的项。您不能从forEach
或每个
回调函数本机中断。然而,许多人使用一种技术来打破这种局面,但有一个定制的例外:
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语句捕获。不要在没有检查的情况下吞下它。使用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
});
我认为根本没有优势,实际上它的性能比较慢。我之所以使用它是因为我喜欢sintax,但我认为这并不比只使用javascriptforEach
好,因为它没有“中断”或“继续”,您可以使用some
或every
。一个优点是,正确实现的each对于稀疏数组更有效,因为它只会迭代存在的成员(类似于……中的),而for循环会在范围内的所有索引上进行迭代。但这不是数组的常见情况。我明白你的意思,当然是的,但我认为你的语法不正确……看起来find是下划线.js方法?我认为更好的解决方案是将函数传递给forEach,这是一个更通用的解决方案,不是吗?语法看起来很简单e、 find
是一种基于Array的方法。prototype
所以你的对象可能不是Array?那么你必须查阅他们的文档。我不确定你所说的更广义的解决方案是什么意思,或者为什么需要这样的解决方案。在这里使用find
非常有表现力,而且你可以看到的代码要少得多。让我来看看k在find()源中,您可以尝试直接调用find
:[].find.call(collections.users.models,函数(u){return u.username===user.username;})
为什么要使用for循环来做这件事呢?这只是为了解决OP关于如何从forEach
或每个
中突破的疑问。但是,如果您需要避免本机for..in
或for..of
循环(可能是根据项目的编码约定指南或其他规定),并且您希望在处理不再需要剩余元素时中断。使用exception
来模拟break
很容易,而且不会破坏代码的可读性。我忘记添加“希望”。)投票支持使用Array.prototype.some
和Array.prototype.every
以获得中断
功能