JavaScript中forEach和for循环的区别

25

我在想:在JavaScript中,forEachfor循环之间是否有任何显著差异。

考虑这个例子:

var myArray = [1,2,3,4];

myArray.forEach(function(value) {
  console.log(value);
});

for (var i = 0; i < myArray.length; i++) {
  console.log(myArray[i]);
}

这是我的一部分研究:

  1. 性能: 根据JsPerf的数据: forEach 比 for 循环略慢。
  2. 可用性: 在使用 forEach 循环时,我们无法在回调函数中使用 break 或 return 终止循环。

例如:你想要判断一个数字是否为质数。我认为使用 for 循环比使用 forEach 循环更容易实现。

  1. 可读性:使用 for 循环可以使代码更易读,而使用 forEach 可能会让代码更加混乱。
  2. 浏览器兼容性:forEach 不支持 IE < 9 ,因此在代码中需要引入一些 shim。

我的问题是:

  1. 使用 forEach 相对于 for 循环有哪些优势?
  2. 在什么情况下,使用 forEach 更为适合?
  3. 为什么 JavaScript 中需要引入 forEach?它有何用处?

从技术上讲,您可以通过抛出错误来中断 for each 循环... 1)观点 2)观点 3)观点。 - epascarello
@Sirko - 我想你的意思是 [1,2,,3,4]。你评论中的数组有五个成员,forforEach 都会访问所有五个成员。但是,如果一个或多个成员不存在(所谓的“稀疏”数组),那么 forEach 将不会访问缺失的成员。 - RobG
@RobG 对的。现在无法更正。 - Sirko
可能是for和foreach之间的区别是什么的重复问题。 - pjmorse
@epascarello 感谢您提出 throw 和 catch 的建议...但这只是一个解决方法...我仍然会使用 for 循环。 - Sachin Jain
9个回答

22

forEachArray 原型上的一个方法。它遍历数组中的每个元素并将其传递给回调函数。

基本上,forEach 是用于“传递数组中每个元素到一个函数”的使用场景的简写方法。以下是一个常见的例子,我认为 Array.forEach 在这种情况下比使用 for 循环更加有用:

// shortcut for document.querySelectorAll
function $$(expr, con) {
    return Array.prototype.slice.call((con || document).querySelectorAll(expr));
}

// hide an element
function hide(el) {
    el.style.display = 'none';
}

// hide all divs via forEach
$$('div').forEach(hide); 

// hide all divs via for
for (var divs = $$('div'), i = 0; i < divs.length; i++) {
    hide(divs[i])
}

如您所见,与 for 循环相比,forEach 语句的可读性有所提高。
另一方面,for 语句更加灵活:它不一定涉及数组。正常的 for 循环的性能略好,因为没有每个元素涉及函数调用。尽管如此,建议在可以编写 forEach 语句时避免使用 for 循环。

1
你肯定提出了一个支持forEach的很好的观点..已接受。 - Sachin Jain
2
但是有什么区别呢?你只给了forEach的信息。 - Vigneshwaran
@Silver Bullet 谢谢,我修改了我的答案,为for提供了更多信息并澄清了区别。 - Lea Rosema

20
在`forEach`循环中,您无法控制数组的迭代方式。经典的`for`循环允许您选择您想要的迭代算法(例如:`i++`、`i--`、`i+=2*i`等)。
然而,使用`forEach`循环要容易得多 - 您不需要处理所有的`i`计数,查找`array[i]`对象——JS会为您完成这些工作。

谢谢你提供这个好建议..+1。关于循环,你可以根据自己的情况来操纵循环索引,这确实是一个非常好的观点。例如:打印偶数。 - Sachin Jain

8
>> sparseArray = [1, 2, , 4];

>> sparseArray.forEach(console.log, console);
1 0 [1, 2, 3: 4] 
2 1 [1, 2, 3: 4] 
4 3 [1, 2, 3: 4] 

>> for(var i = 0; i < sparseArray.length; ++i) { console.log(sparseArray[i]) };
1
2
undefined
4 

forEach 是 JavaScript 中用于实现表达式列表推导的最新补充。在这里,你可以看到 forEach 跳过了从未设置过的元素,但是使用 for 循环最好的做法是检查是否为undefinednull,这两者都可以被设置为值并被 forEach 接收到。除非你期望有缺失的值,否则 forEach 相当于 for 循环,但请注意,你无法提前停止循环,需要使用 every


2
简单来说,根据以下文章和研究,主要区别如下: For循环
  1. 它是迭代数组的最初方法之一
  2. 速度更快
  3. 您可以使用此关键字break退出循环
  4. 在我看来,它主要用于整数(数字)计算
  5. 参数为(迭代器、计数器、增量器)
ForEach循环
  1. 这是一种较新的方法,可用较少的代码迭代数组
  2. 更易于阅读
  3. 让您在范围内保留变量
  4. 使用i <= >=等情况时,意外错误的几率较低
  5. 参数为(迭代器、项目索引、整个数组)
https://alligator.io/js/foreach-vs-for-loops/

1

forEach

  1. forEach是Array原型上的一个方法。
  2. 它很容易使用。
  3. 它包含一个回调函数,数组中的每个元素都会被传递给回调函数。
  4. 由于回调函数的存在,你不能在forEach中使用await,否则输出将与预期不同。
  5. 由于回调函数的存在,它比for循环慢。
  6. 由于回调的存在,你不能使用break。

For循环

  1. 在for循环中,你需要一个索引、一个条件和一个增量/减量的索引变量。
  2. 它比forEach更快。
  3. 你可以使用break。
  4. 它可以与await一起使用。

0

来自Eric Sarrion的书《JavaScript从前端到后端》:

for()循环和forEach()方法之间的区别

为了展示这两种方法(for() 循环forEach()方法)之间的区别,让我们在数组中引入一个新元素,位于索引10处,知道创建数组时使用的最后一个索引是4。因此,我们创建了一个比当前数组的最后一个元素远得多的新元素。数组将如何对这个扩展做出反应?

// original array
var tab = ["Element 1", "Element 2", "Element 3", "Element 4", 
"Element 5"];

// adding a new element in the array, at index 10
tab[10] = "Element 9";
console.log("tab =", tab);

// display the array with a for() loop
console.log("Access to each element by a for() loop");
for (var i = 0; i < tab.length; i++) console.log("tab[" + i + "]=", tab[i]);

// display the array by the forEach() method
console.log("Access to each element by the forEach() method");
tab.forEach(function(elem, i) {
 console.log("tab[" + i + "]=", elem);
});

我们使用 tab[10] = "Element 9" 向数组中添加一个元素,然后使用 for() 循环forEach() 方法 显示数组的内容。结果显示在下图中:

enter image description here

for()循环的显示表明,索引为5到9的元素存在,但其值为未定义,因为实际上没有为数组的这些索引插入任何值。然而,for()循环会显示索引为5到9的未定义值。

相反,forEach()方法仅向参数中指定的回调函数提供实际在数组中受影响的数组元素。因此,它避免了程序中未分配的索引为5到9的元素。


0

forEachArray原型上的一个方法,它接受一个函数表达式作为参数,在每次迭代时执行该函数,并在该函数内将当前迭代的数组项作为第一个参数传递。

ForEach结构:

// Arrow function
forEach((element) => { /* … */ })
forEach((element, index) => { /* … */ })
forEach((element, index, array) => { /* … */ })

另一方面,for循环是JavaScript语言本身固有的结构。 For循环重复执行,直到指定条件评估为false。数组操作是可以在此for循环体内使用的一件事情,但不一定是唯一的事情,而forEach仅适用于数组。 For循环结构:
for ([initialExpression]; [conditionExpression]; [incrementExpression]) {
 /* statement */
}

For循环在性能上略优于forEach,但建议尽可能使用forEach以获得更易读的代码。


0

在JavaScript中,forEach循环和for循环之间存在差异。

就性能而言,我更喜欢for循环而不是forEach循环。 这只是我在使用forEach循环时遇到的一些问题之一。

let abc = [1,2,3] 

abc.forEach((e) => { 
   delete e; 
}) 

console.log(abc)  //Array(3) [ 1, 2, 3 ]

for (let i = 0; i < abc.length; i++) { 
   delete abc[i]; 
} 

console.log(abc)  //Array(3) [ <3 empty slots> ]

0

除了灵活性之外,我使用for循环的一个主要原因是如果我需要提前从循环中break出来。

在下面的示例代码中,如果您只想返回数组中特定的value,您可以使用if语句检查是否符合您的条件,然后从循环中退出。 forEach方法将遍历每个食品,这可能会导致性能问题。

//Assume that foodArray has been declared
for (let i = 0; i < foodArray.length; i++) {
  if (foodArray[i].name === 'Pizza') {
    console.log('PIZZA EXISTS');
    break;
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接