Short circuit Array.forEach like calling break

Short circuit Array.forEach like calling break

技术背景

在 JavaScript 中,Array.prototype.forEach 方法用于对数组的每个元素执行一次提供的函数。然而,forEach 方法没有内置的 break 机制来提前终止循环。但在实际开发中,我们可能会有提前终止循环的需求,因此需要寻找其他方法来实现类似 break 的功能。

实现步骤

1. 使用异常抛出的方式

可以通过抛出异常来提前终止 forEach 循环。示例代码如下:

1
2
3
4
5
6
7
8
9
10
var BreakException = {};

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

2. 使用 Array#some 方法

some 方法会在数组元素的回调函数返回 true 时立即停止执行,并返回 true。示例代码如下:

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

3. 使用 for...of 循环

ES6 引入的 for...of 循环可以使用 break 语句来提前终止循环。示例代码如下:

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

4. 使用 Array.prototype.every 方法

every 方法会在回调函数返回 false 时停止执行,并返回 false。示例代码如下:

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

// ES6 箭头函数写法
[1,2,3].every( el => el !== 1 )

5. 自定义 forEach 函数

可以自定义一个 forEach 函数,通过传递一个 _break 函数来实现提前终止循环。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function forEach(array, cb) {
var shouldBreak;
function _break() { shouldBreak = true; }
for (var i = 0, bound = array.length; i < bound; ++i) {
if (shouldBreak) { break; }
cb(array[i], i, array, _break);
}
}

// Usage
forEach(['a','b','c','d','e','f'], function (char, i, array, _break) {
console.log(i, char);
if (i === 2) { _break(); }
});

最佳实践

  • 如果需要提前终止循环,优先考虑使用 for...of 循环,因为它的语法简洁,且可以直接使用 break 语句。
  • 如果需要对数组元素进行条件判断并提前终止循环,可以使用 Array#someArray.prototype.every 方法。
  • 避免使用抛出异常的方式来终止 forEach 循环,因为异常处理会影响代码的性能和可读性。

常见问题

1. 使用 Array#someArray.prototype.every 方法替代 for...break 是否合适?

不建议使用 Array#someArray.prototype.every 方法来替代 for...break,因为这两个方法的本意是返回布尔值,使用它们来模拟 for...break 会使代码的意图不清晰,增加代码的理解难度。

2. 自定义 forEach 函数是否会影响性能?

自定义 forEach 函数的性能与原生的 forEach 方法相当,但由于增加了额外的逻辑,可能会稍微降低性能。在性能要求不高的场景下,可以使用自定义 forEach 函数来实现提前终止循环的功能。


Short circuit Array.forEach like calling break
https://119291.xyz/posts/short-circuit-array-foreach-like-calling-break/
作者
ww
发布于
2025年5月19日
许可协议