协慌网

登录 贡献 社区

短路 Array.forEach 就像调用 break

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

如何在 JavaScript 中使用新的forEach方法执行此操作?我试过return;return false;breakbreak崩溃并return只会继续迭代。

答案

没有内置的能力来break forEach 。要中断执行,你必须抛出某种异常。例如。

var BreakException = {};

try {
  [1, 2, 3].forEach(function(el) {
    console.log(el);
    if (el === 2) throw BreakException;
  });
} catch (e) {
  if (e !== BreakException) throw e;
}

JavaScript 异常并不是非常漂亮。如果你真的需要break它,传统的for循环可能更合适。

使用Array#some

相反,使用Array#some

[1, 2, 3].some(function(el) {
  console.log(el);
  return el === 2;
});

这是有效的,因为只要以数组顺序执行的任何回调返回truesome回调就会返回true ,从而使其余的执行短路。

some ,它的反转every (它将在return false时停止),而forEach都是 ECMAScript 第五版方法,需要将它们添加到缺少它们的浏览器上的Array.prototype

现在有一种更好的方法可以在 ECMAScript2015(又名 ES6)中使用 new for for 循环来完成这项工作。例如,此代码不会在数字 5 之后打印数组元素:

let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
for (let el of arr) {
  console.log(el);
  if (el === 5) {
    break;
  }
}

来自文档:

for ... infor ...语句都迭代了某些东西。它们之间的主要区别在于它们迭代的内容。 for ... in语句以原始插入顺序迭代对象的可枚举属性。 for ... of语句迭代可迭代对象定义为迭代的数据。

在迭代中需要索引吗?您可以使用Array.entries()

for (const [index, el] of arr.entries()) {
  if ( index === 5 ) break;
}

您可以使用每种方法:

[1,2,3].every(function(el) {
    return !(el === 1);
});

ES6

[1,2,3].every( el => el !== 1 )

对于旧浏览器支持使用:

if (!Array.prototype.every)
{
  Array.prototype.every = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this &&
          !fun.call(thisp, this[i], i, this))
        return false;
    }

    return true;
  };
}

这里有更多细节。