「译」forEach循环中你不知道的3件事

前言

本文925字,阅读大约须要7分钟。前端

总括: forEach循环中你不知道的3件事。async

自弃者扶不起,自强者击不倒。函数

正文

你以为你真的学会用forEach了么?工具

这是我以前对forEach循环的理解:就是一个普通语义化以后的for循环,能够被break,continue,returnoop

这篇文章将向你展现forEach中你可能不了解的3件事。学习

1. return不会中止循环

你以为下面的代码在打印12以后会中止么?this

array = [1, 2, 3, 4];
array.forEach(function (element) {
  console.log(element);

  if (element === 2) 
    return;
  
});
// Output: 1 2 3 4

答案是不会,上述代码会正常打印1,2,3,4。若是你有Java背景,你也许会很诧异,这怎么可能呢?code

缘由是咱们在forEach函数中传了一个回调函数,该回调函数的行为和普通函数同样,咱们return操做其实就是普通函数中return。因此并不符合咱们预期将forEach循环打断。ip

MDN官方文档:element

注意: 除了抛出异常之外,没有办法停止或跳出 forEach() 循环。若是你须要停止或跳出循环,forEach() 方法不是应当使用的工具。

咱们将上述代码改写:

const array = [1, 2, 3, 4];
const callback = function(element) {
    console.log(element);
    
    if (element === 2) 
      return; // would this make a difference? no.
}
for (let i = 0; i < array.length; i++) {
    callback(array[i]);
}
// Output: 1 2 3 4

这就是上述代码实际的执行思路,return操做只做用于当前的函数,天然不会对for循环产生影响

2. 不能break

下面的代码你以为会被break掉么?

const array = [1, 2, 3, 4];
array.forEach(function(element) {
  console.log(element);
  
  if (element === 2) 
    break;
});
// Output: Uncaught SyntaxError: Illegal break statement

不会,甚至这行代码都不会运行,直接报错了。

那么这段代码如何达到咱们本来想达到的效果呢?

用普通for循环就行了:

const array = [1, 2, 3, 4];
for (let i = 0; i < array.length; i++) {
  console.log(array[i]);
  
  if (array[i] === 2) 
    break;
}
// Output: 1 2

3. 不能continue

下面代码会是跳过2只打印一、三、4吗?

const array = [1, 2, 3, 4];
array.forEach(function (element) {
  if (element === 2) 
    continue;
  
  console.log(element);
});
// Output: Uncaught SyntaxError: Illegal continue statement: no surrounding iteration statement

一样不会,和break同样,报错,这行代码以后甚至都不会运行。

怎么达到预期呢?

仍是使用普通的for循环来解决:

for (let i = 0; i < array.length; i++) {
  if (array[i] === 2) 
    continue;
  console.log(array[i]);
}
// Output: 1 3 4

译者补充

forEach函数的实际运行原理实际上是这样的,伪代码以下:

let arr = [1, 2];
arr.forEach(function(ele) {
	console.log(ele);
}); 
// output: 1, 2
// 上面代码等同于
function func(ele) {
  console.log(ele);
}
for (let i = 0; i < arr.length; i++) {
	func(arr[i])
}
// output: 1, 2

实际上forEach的polyfill实现也是这样的,在forEach函数中执行一个for循环,在for循环里调用回调函数。

所以,像下面代码天然不会符合预期:

let arr = [1, 2];
let sum = 0;
function add(a) {
	return a;
}
arr.forEach(async function(ele) {
  sum += await add(ele);
});
console.log(sum);
// Output:0

改写以下:

let arr = [1, 2];
let sum = 0;
function add(a) {
	return a;
}
for (let i = 0; i < arr.length; i++) {
	sum += await add(arr[i]);
}
console.log(sum);
// Output:3

订阅更多文章可关注「前端进阶学习」,回复「666」,获取一揽子前端技术书籍

前端进阶学习

相关文章
相关标签/搜索