[1,2,3].forEach(function(el) {
    if(el === 1) break;
});

如何在JavaScript中使用新的forEach方法实现这一点?我尝试过返回;,return false;和断裂。break崩溃,return只会继续迭代。


当前回答

如果您想使用Dean Edward的建议并抛出StopIteration错误以跳出循环而不必捕获错误,则可以使用以下函数(最初来自此处):

// Use a closure to prevent the global namespace from be polluted.
(function() {
  // Define StopIteration as part of the global scope if it
  // isn't already defined.
  if(typeof StopIteration == "undefined") {
    StopIteration = new Error("StopIteration");
  }

  // The original version of Array.prototype.forEach.
  var oldForEach = Array.prototype.forEach;

  // If forEach actually exists, define forEach so you can
  // break out of it by throwing StopIteration.  Allow
  // other errors will be thrown as normal.
  if(oldForEach) {
    Array.prototype.forEach = function() {
      try {
        oldForEach.apply(this, [].slice.call(arguments, 0));
      }
      catch(e) {
        if(e !== StopIteration) {
          throw e;
        }
      }
    };
  }
})();

上述代码将使您能够运行以下代码,而无需执行自己的try-catch子句:

// Show the contents until you get to "2".
[0,1,2,3,4].forEach(function(val) {
  if(val == 2)
    throw StopIteration;
  alert(val);
});

需要记住的一点是,如果Array.prototype.forEach函数已经存在,则只会更新它。如果它还不存在,它将不会修改它。

其他回答

不幸的是,在这种情况下,如果不使用forEach会更好。而是使用一个常规的for循环,它现在将完全按照您的预期工作。

var array = [1, 2, 3];
for (var i = 0; i < array.length; i++) {
  if (array[i] === 1){
    break;
  }
}
const Book = {"Titles":[                          
    {"Book3" : "BULLETIN 3"},
    {"Book1" : "BULLETIN 1"},
    {"Book2" : "BULLETIN 2"}    
]}

const findbystr = function(str) { 
    Book.Titles.forEach(function(data) { 
        if (typeof data[str] != 'undefined') {
            return data[str];
        } 
    }, str) 
}

book = findbystr('Book1');

console.log(book);

引用Array.prototype.forEach()的MDN文档:

除此之外,无法停止或中断forEach()循环通过抛出异常。如果您需要这样的行为,.forEach()方法是错误的工具,请改用普通循环。如果要测试谓词的数组元素并需要布尔返回值,则可以改用every()或some()。

对于您的代码(在问题中),如@bobince所建议的,请改用Array.protocol.some()。它非常适合您的用例。

Array.pr原型.some()对数组中的每个元素执行一次回调函数,直到找到一个回调返回真值(当转换为布尔值时变为真)的元素。如果找到这样的元素,some()立即返回true。否则,some()返回false。回调仅对已赋值数组的索引调用;对于已删除或从未赋值的索引,不会调用它。

简短回答:用于。。。为此中断或更改代码以避免中断forEach。不要使用.some()或.every()来模拟。。。打破重写代码以避免。。。中断循环,或用于。。。打破每次你使用这些方法。。。上帝杀死了小猫。

长答案:

.some()和.every()都返回布尔值,如果有任何元素的传递函数返回true,.some(返回true,如果有元素的传递的函数返回false,则every返回false。这就是函数的含义。使用函数来实现它们并不意味着什么,这比使用表来布局而不是CSS要糟糕得多,因为这会让所有阅读代码的人感到沮丧。

此外,使用这些方法的唯一可能方法是。。。break替代方法是产生副作用(在.some()回调函数之外更改一些vars),这与for。。。打破

因此,使用.some()或.every()作为。。。断环替代方案并没有副作用,这对。。。打破,这是令人沮丧的,所以这不是更好的。

您可以随时重写代码,这样就不需要。。。打破您可以使用.filter()过滤数组,也可以使用.slice()等拆分数组,然后使用.forEach()或.map()处理该部分数组。

这是一个for循环,但像forEach()一样在循环中维护对象引用,但可以中断。

var arr = [1,2,3];
for (var i = 0, el; el = arr[i]; i++) {
    if(el === 1) break;
}