因此,当您谈论for
循环时,您指的是实际的for
循环,而不是for...in
(不应在数组上使用)。似乎存在一些误解,让我从这个角度开始:
for
循环不是用于循环遍历数组的。并不是说你不应该或者它不好,但那不是它的主要功能 - 它只是循环直到满足条件然后停止。最常见的语法恰好是for (var i =0; i < max; i++)
,它很适用于数组循环,但这并不意味着您不能使用其他的语法,例如for (var i = 100; Number.isInteger(i); i = i/2)
。因此,针对您的问题,以下是答案:
1. forEach
是否跳过数组中缺失的项?
答案:是的
forEach
是一个数组方法,与map
、reduce
等一起,它确实跳过未分配的插槽。这有助于处理稀疏数组,例如
var arr = [];
arr[5] = "five";
arr[7] = "seven";
arr[10] = "ten";
console.log("---using forEach---");
arr.forEach(function(item) {
console.log(item);
});
console.log("---using a for-loop---");
for (var i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
这是一个简单的例子,说明使用稀疏数组循环的原因 - 正如您所看到的,您可以获得更少的代码执行。这里还有一个稍微复杂一些的例子:
var arr = [];
arr[5] = "five";
arr[42] = "the answer";
arr[9001] = "over nine thousand";
arr.forEach(function(item) {
console.log(item);
});
当你只有三个项目时,一个简单的for
循环会执行(字面上)超过九千次。
我必须在这里澄清一些事情-未设置值是你没有分配任何内容的索引。分配undefined
仍然算作分配:
var arr = [];
arr[5] = "five";
arr[7] = undefined;
arr[10] = "ten";
arr.forEach(function(item) {
console.log(item);
});
2. forEach
方法是否使用内部计数器?
答案:是的
你可以很容易地获取当前结果,因为它会被传递到回调函数中。
var arr = [];
arr[5] = "five";
arr[42] = "the answer";
arr[9001] = "over nine thousand";
arr.forEach(function(item, index) {
console.log(index, "-", item);
});
3. forEach
的执行顺序是什么
答案:从零开始,按升序执行
以上内容应该已经向您展示了这个问题的答案。以下是另一个快速示例:
var alphabet = ["a", "b", "c", "d", "e", "f", "g" ];
alphabet.forEach(function(letter, index) {
console.log(index, letter);
})
4. for
和forEach
之间的区别
答案: 很难进行比较
两者之间的区别正如我在开始时所提到的 - for
是JavaScript中的通用循环运算符 - 你可以使用它来遍历数组,但也可以用于各种其他目的。相比之下,forEach
专门绑定在数组上。实际上很难进行真正的比较,但如果我们仅仅限制为对其在数组上的使用,那么以下是一些要点:
for
- + 你可以使用
break
或 return
提前退出循环,因此不需要遍历整个数组
- + 你可以控制数组的遍历,因此可以从末尾开始并向下计数 (
for (var i = arr.length; i >= 0; i--)
),或者甚至可以回退或跳过项 (在循环体内执行 i--
或 i += 2
)
- + 因为在许多其他语言中都使用,所以被广泛认可作为循环机制
- +/- 即使对于稀疏数组,你也将遍历整个数组长度。
- - 即使你不关心它,也必须维护循环计数器。
forEach
- + 能够很好地处理稀疏数组
- + 接受回调函数,因此可以通过将它们传递到
.forEach
调用中来重用函数
- + 上述的另一个好处是回调体内所有内容的功能作用域(尽管使用ES6的
let
和const
时这些作用得到了减少)
- + 习惯用法JavaScript
- +/- 对于稀疏数组,只会遍历存在的项
- - 不能提前退出循环,尽管你可能会使用
find
。
- - 你无法控制数组的遍历方式。
PS: for...of
也值得一提
感谢 @Bergi,我记得我确实想在这里包含一些内容:
你没有提到的一个循环是
for...of
循环,它的语法与
for...in
循环相似,但它被设计用于处理数组以及其他可迭代对象。这是一个相对较新的构造(至少比
forEach
要新),因为它在ES6规范中,所以广泛的网络支持可能不会有,但它是上述两个的替代方案。使用起来非常简单:
var arr = [];
arr[5] = "five";
arr[7] = "seven";
arr[10] = "ten";
for (item of arr) {
console.log(item);
}
所以,简单来说,它的工作方式类似于
for
循环,因为它会遍历所有内容,但您不必声明和维护计数器。