JavaScript 迭代

示例

传统for循环

传统for循环包含三个组成部分:

  1. 初始化:在第一次执行look块之前执行

  2. 条件:每次在执行循环块之前都要检查条件,如果为false则退出循环

  3. 事后思考:循环块执行后每次执行

这三个组件之间用;符号分隔。这三个组件中每个组件的内容都是可选的,这意味着以下是for可能的最小循环:

for (;;) {
    // 做东西
}

当然,您需要在该-loop内添加if(condition === true) { break; }  或if(condition === true) { return; },for以使其停止运行。

通常,尽管如此,初始化用于声明索引,条件用于将索引与最小值或最大值进行比较,事后才用于增加索引:

for (var i = 0, length = 10; i < length; i++) {
    console.log(i);
}


使用传统for循环遍历数组

遍历数组的传统方法是:

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

或者,如果您希望向后循环,请执行以下操作:

for (var i =myArray.length- 1; i > -1; i--) {
    console.log(myArray[i]);
}

但是,可能有多种变体,例如以下一种:

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

...或者这个...

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

...或这个:

var key = 0, value;
for (; value = myArray[key++];){
    console.log(value);
}

哪种效果最好,很大程度上取决于个人喜好和您要实现的特定用例。

请注意,所有浏览器(包括非常老的浏览器)都支持所有这些变体!


一while环

for循环的一种替代方法是while循环。要遍历数组,可以执行以下操作:

var key = 0;
while(value = myArray[key++]){
    console.log(value);
}

像传统的for循环一样,while即使最古老的浏览器也支持循环。

另外,请注意,每个while循环都可以重写为for循环。例如,上述while循环的行为与此for-loop完全相同:

for(var key = 0; value = myArray[key++];){
    console.log(value);
}


for...in

在JavaScript中,您还可以执行以下操作:

for (i in myArray) {
    console.log(myArray[i]);
}

但是,应谨慎使用,因为for在所有情况下,它的行为都与传统循环不同,并且需要考虑潜在的副作用。请参阅为什么在数组迭代中使用“ for ... in”是个坏主意?更多细节。

for...of

在ES 6中,for-of建议使用循环来遍历数组的值:

6
let myArray = [1, 2, 3, 4];
for (let value of myArray) {
  let twoValue = value * 2;
  console.log("2 * value is: %d", twoValue);
}

以下示例显示了for...of循环和for...in循环之间的区别:

6
let myArray = [3, 5, 7];
myArray.foo = "hello";

for (var i in myArray) {
  console.log(i); // logs 0, 1, 2, "foo"
}

for (var i of myArray) {
  console.log(i); // 日志3、5、7
}

Array.prototype.keys()

该方法可用于迭代索引,如下所示:Array.prototype.keys()

6
let myArray = [1, 2, 3, 4];
for (let i of myArray.keys()) {
  let twoValue = myArray[i] * 2;
  console.log("2 * value is: %d", twoValue);
}

Array.prototype.forEach()

该.forEach(...)方法是ES 5及更高版本中的一个选项。所有现代浏览器以及Internet Explorer 9及更高版本均支持该功能。

5
[1, 2, 3, 4].forEach(function(value, index, arr) {
  var twoValue = value * 2;
  console.log("2 * value is: %d", twoValue);
});

与传统for循环相比,我们无法从中跳出循环。在这种情况下,请使用循环,或使用下面介绍的部分迭代。.forEach()for

在所有版本的JavaScript中,都可以使用传统的C样式for循环遍历数组的索引。

var myArray = [1, 2, 3, 4];
for(var i = 0; i < myArray.length; ++i) {
  var twoValue = myArray[i] * 2;
  console.log("2 * value is: %d", twoValue);
}

也可以使用while循环:

var myArray = [1, 2, 3, 4],
    i = 0, sum = 0;
while(i++ < myArray.length) {
  sum += i;
}
console.log(sum);


Array.prototype.every

从ES5开始,如果要迭代数组的一部分,则可以使用Array.prototype.every,迭代直到我们返回false:

5
// [] .every()一旦发现错误结果就会停止
// 因此,此迭代将停止在值7上(因为7%2!== 0)
[2, 4, 7, 9].every(function(value, index, arr) {
  console.log(value);
  return value % 2 === 0; // 迭代直到找到奇数
});

在任何JavaScript版本中均等效:

var arr = [2, 4, 7, 9];
for (var i = 0; i <arr.length&& (arr[i] % 2 !== 0); i++) { // 迭代直到找到奇数
  console.log(arr[i]);
}


Array.prototype.some

Array.prototype.some迭代直到我们返回true:

5
// [] .some在发现错误结果后立即停止
// 因此,此迭代将停止在值7上(因为7%2!== 0)
[2, 4, 7, 9].some(function(value, index, arr) {
  console.log(value);
  return value === 7; // 迭代直到找到值7
});

在任何JavaScript版本中均等效:

var arr = [2, 4, 7, 9];
for (var i = 0; i <arr.length&& arr[i] !== 7; i++) {
  console.log(arr[i]);
}


图书馆

最后,许多实用程序库也有其自己的foreach变体。最受欢迎的三个是:

jQuery.each(),在jQuery中

$.each(myArray, function(key, value) {
    console.log(value);
});

_.each(),在Underscore.js中

_.each(myArray, function(value, key, myArray) {
    console.log(value);
});

_.forEach(),在Lodash.js中

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


另请参阅以下关于SO的问题,此信息最初在何处发布:

  • 遍历JavaScript中的数组