在JavaScript中循环遍历数组

时间:2010-06-10 00:04:27

标签: javascript arrays loops for-loop

在Java中,您可以使用for循环遍历数组中的对象,如下所示:

String[] myStringArray = {"Hello", "World"};
for (String s : myStringArray)
{
    // Do something
}

你能用JavaScript做同样的事吗?

47 个答案:

答案 0 :(得分:3371)

您有几种选择:

1。顺序for循环:

var myStringArray = ["Hello","World"];
var arrayLength = myStringArray.length;
for (var i = 0; i < arrayLength; i++) {
    console.log(myStringArray[i]);
    //Do something
}

<强>赞成

  • 适用于各种环境
  • 您可以使用breakcontinue流程控制语句

<强>缺点

2。 Array.prototype.forEach

ES5规范。介绍了很多非常有用的数组方法,其中之一是Array.prototype.forEach,它为我们提供了一种迭代数组的简短方法:

const array = ["one", "two", "three"]
array.forEach(function (item, index) {
  console.log(item, index);
});

作为编写ES5规范的时间差不多9年了。发布时间(2009年12月),它已经被桌面,服务器和移动环境中的几乎所有现代引擎实现,因此使用它们是安全的。

使用ES6箭头函数语法,它更简洁:

array.forEach(item => console.log(item));

箭头功能也正在广泛实施,除非您计划支持非常旧的平台(例如IE11),您也可以安全使用。

<强>赞成

  • 非常短暂和娴熟。
  • 声明

<强>缺点

  • 无法使用break / continue

通常,您可以通过在迭代数组元素之前过滤数组元素来替换命令循环中break的需要,例如:

array.filter(item => item.condition < 10)
     .forEach(item => console.log(item))

请记住,如果你正在迭代一个数组来构建另一个数组,你应该使用map,我已经多次看到过这种反模式。

<强>反模式:

const numbers = [1,2,3,4,5], doubled = [];

numbers.forEach((n, i) => { doubled[i] = n * 2 });

map 的正确用例:

const numbers = [1,2,3,4,5];
const doubled = numbers.map(n => n * 2);

console.log(doubled);

此外,如果您尝试数组减少为某个值,例如,您想要对数字数组求和,则应使用 reduce 方法。< / p>

<强>反模式:

const numbers = [1,2,3,4,5];
const sum = 0;
numbers.forEach(num => { total += num });

正确使用 reduce

const numbers = [1,2,3,4,5];
const sum = numbers.reduce((total, n) => total + n, 0);

console.log(sum);

3。 ES6 for-of声明

ES6标准引入了可迭代对象的概念,并定义了一个用于遍历数据的新构造,即for...of语句。

此语句适用于任何类型的可迭代对象,也适用于生成器。

根据定义,数组对象是ES6中内置的可迭代对象,因此您可以对它们使用此语句:

let colors = ['red', 'green', 'blue'];
for (const color of colors){
  console.log(color);
}

<强>赞成

  • 可以迭代各种各样的对象。
  • 可以使用常规流量控制语句(break / continue)。
  • 用于迭代串行异步值。

<强>缺点

不要使用for...in

@zipcodeman建议使用for...in语句,但是对于迭代数组for-in应该避免,该语句是枚举对象属性。

它不应该用于类似数组的对象,因为:

  • 无法保证迭代的顺序,可能无法按数字顺序访问数组索引。
  • 还枚举了继承的属性。

第二点是它可以给你带来很多问题,例如,如果你扩展Array.prototype对象以包含一个方法,那么该属性也将被枚举。

例如:

Array.prototype.foo = "foo!";
    var array = ['a', 'b', 'c'];
    
    for (var i in array) {
      console.log(array[i]);
    }

以上代码将控制“a”,“b”,“c”和“foo!”。

如果您使用一些严重依赖原生原型增强的库(例如MooTools),那么这个问题尤为突出。

我前面说过的for-in语句是枚举对象属性,例如:

var obj = {
      "a": 1,
      "b": 2,
      "c": 3
    };

    for (var prop in obj) {
      if (obj.hasOwnProperty(prop)) { 
      // or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety...
        console.log("prop: " + prop + " value: " + obj[prop])
      }
    }

在上面的示例中,hasOwnProperty方法只允许枚举自己的属性,就是它,只有对象物理上具有的属性,没有继承的属性。

我建议你阅读以下文章:

答案 1 :(得分:1054)

是的,假设您的实施包含for...of中引入的ECMAScript 2015功能(“和谐”版本)......这些天是非常安全的假设。

它的工作原理如下:

// REQUIRES ECMASCRIPT 2015+
var s, myStringArray = ["Hello", "World"];
for (s of myStringArray) {
  // ... do something with s ...
}

或者更好,因为ECMAScript 2015还通过letconst提供了块范围的变量:

// REQUIRES ECMASCRIPT 2015+
const myStringArray = ["Hello", "World"];
for (const s of myStringArray) {
  // ... do something with s ...
}
// s is no longer defined here

关于稀疏数组的注释:JavaScript中的数组实际上可能不会存储其length报告的项目数;报告的数字只是一个大于存储值的最高索引的数字。如果数组包含的元素少于其长度所指示的元素,则称其为稀疏。例如,仅在索引3,12和247处具有包含项的数组是完全合法的。这样的数组的length被报告为248,尽管它实际上只存储了3个值。如果您尝试访问任何其他索引处的项目,则该数组似乎在那里具有undefined值。因此,当您想要“循环”一个数组时,您有一个问题需要回答:您是否想要遍历其长度所指示的整个范围并处理undefined s以查找任何缺失的元素,或者您只想要处理实际存在的元素?两种方法都有很多应用;它只取决于你使用数组的目的。

如果使用for .. of迭代数组,则循环体执行length次,循环控制变量设置为undefined对于数组中实际不存在的任何项目。根据“执行某些操作”代码的详细信息,该行为可能是您想要的,但如果这不是您想要的,则应使用不同的方法。

当然,一些开发人员别无选择,只能使用不同的方法,因为无论出于何种原因,他们都会定位一个尚不支持for的JavaScript版本...... of

只要您的JavaScript实现符合ECMAScript规范的以前的版本(例如,排除9之前的Internet Explorer版本),就可以使用{{3迭代器方法而不是循环。在这种情况下,您传递一个要在数组中的每个项目上调用的函数:

var myStringArray = [ "Hello", "World" ];
myStringArray.forEach( function(s) { 
     // ... do something with s ...
} );

for ... of不同,.forEach仅为实际包含值的元素调用函数。如果通过我们的假设数组有三个元素,长度为248,它只会调用函数三次,而不是248次。它还区分了缺少的元素和实际设置为undefined的元素;对于后者,它仍将调用该函数,将undefined作为参数传递。如果您希望处理稀疏数组,即使您的口译员支持.forEach ... for,也可以采用of

最终选项适用于所有版本的JavaScript,Array#forEach。您只需从0到小于长度计数,并使用计数器作为索引。基本循环如下所示:

var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
  s = myStringArray[i];
  // ... do something with s ...
}

这种方法的一个优点是您可以选择如何处理稀疏数组;对于任何缺失的元素,上面的代码将运行循环体整整length次,s设置为undefined,就像for一样。{{1} }。如果您只想处理稀疏数组的实际存在元素,例如of,则可以在索引上添加简单的.forEach测试:

in

将长度值分配给局部变量(与在循环条件中包含完整的var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length; for (i=0; i<len; ++i) { if (i in myStringArray) { s = myStringArray[i]; // ... do something with s ... } } 表达式相反)可以在性能上产生显着差异,因为它每次都会跳过属性查找;在我的机器上使用Rhino,加速比为43%。

您可以在循环初始化子句中看到完成长度缓存,如下所示:

myStringArray.length

其他人提到的var i, len, myStringArray = [ "Hello", "World" ]; for (len = myStringArray.length, i=0; i<len; ++i) { ... for语法用于循环对象的属性;因为JavaScript中的数组只是一个具有数字属性名称的对象(以及一个自动更新的in属性),所以理论上可以用它循环一个数组。但问题在于它并不局限于数值属性值(请记住,即使方法实际上只是其值为闭包的属性),也不保证按数字顺序迭代它们。因此,length ... for语法应该用于循环遍历数组。

答案 2 :(得分:426)

您可以使用map,这是一种功能性编程技术,也可以在PythonHaskell等其他语言中使用。

[1,2,3,4].map( function(item) {
     alert(item);
})

一般语法是:

array.map(func)

通常func会有一个参数,它是数组的一个项目。但是在JavaScript的情况下,它可以采用第二个参数,即项目的索引,以及第三个参数,即数组本身。

array.map的返回值是另一个数组,因此您可以像这样使用它:

var x = [1,2,3,4].map( function(item) {return item * 10;});

现在x是[10,20,30,40]

您不必编写内联函数。它可能是一个单独的功能。

var item_processor = function(item) {
      // Do something complicated to an item
}

new_list = my_list.map(item_processor);

这将等同于:

 for (item in my_list) {item_processor(item);}

除非你没有得到new_list

答案 3 :(得分:111)

在JavaScript中,不建议使用for-in循环遍历数组,但最好使用for循环,例如:

for(var i=0, len=myArray.length; i < len; i++){}

它也被优化(“缓存”数组长度)。如果您想了解更多信息,请read my post on the subject

答案 4 :(得分:105)

for(var s of myStringArray){

(直接回答你的问题:现在你可以!)

大多数其他答案都是正确的,但他们没有提及(截至撰写本文时) ECMA脚本 6 2015 带来了新的进行迭代的机制, for..of 循环。

这种新语法是在javascript中迭代数组的最优雅方式(只要你不需要迭代索引),但它还没有被浏览器广泛支持。

它目前适用于Firefox 13 +,Chrome 37+,它本身不能与其他浏览器一起使用(请参阅下面的浏览器兼容性)。幸运的是,我们有JS编译器(例如Babel),它们允许我们今天使用下一代功能。

它也适用于Node(我在版本0.12.0上测试过它)。

迭代数组

// You could also use "let" instead of "var" for block scope.
for (var letter of ["a", "b", "c"]) { 
   console.log(letter); 
}

迭代一组对象

var band = [
  {firstName : 'John', lastName: 'Lennon'}, 
  {firstName : 'Paul', lastName: 'McCartney'}
];

for(var member of band){
  console.log(member.firstName + ' ' + member.lastName); 
}

迭代生成器:

(从https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of提取的示例)

function* fibonacci() { // a generator function
  let [prev, curr] = [1, 1];
  while (true) {
    [prev, curr] = [curr, prev + curr];
    yield curr;
  }
}

for (let n of fibonacci()) {
  console.log(n);
  // truncate the sequence at 1000
  if (n >= 1000) {
    break;
  }
}

兼容性表: http://kangax.github.io/es5-compat-table/es6/#For..of loops

规范: http://wiki.ecmascript.org/doku.php?id=harmony:iterators

}

答案 5 :(得分:87)

Opera,Safari,Firefox和Chrome现在都共享一组增强的数组方法,用于优化许多常见的循环。

您可能不需要所有这些,但它们可能非常有用,或者如果每个浏览器都支持它们。

Mozilla Labs发布了他们和WebKit都使用的算法,以便您自己添加。

过滤器会返回满足某些条件或测试的项目数组。

如果每个数组成员都通过测试,则每个都返回true。

某些如果通过测试则返回true。

forEach 在每个数组成员上运行一个函数,但不返回任何内容。

map 与forEach类似,但它返回每个元素的操作结果数组。

这些方法都为它们的第一个参数提供了一个函数,并且有一个可选的第二个参数,该参数是一个对象,当它们循环遍历函数时,它们要在数组成员上施加范围。

忽略它直到你需要它。

indexOf lastIndexOf 找到与其参数完全匹配的第一个或最后一个元素的适当位置。

(function(){
    var p, ap= Array.prototype, p2={
        filter: function(fun, scope){
            var L= this.length, A= [], i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        val= this[i];
                        if(fun.call(scope, val, i, this)){
                            A[A.length]= val;
                        }
                    }
                    ++i;
                }
            }
            return A;
        },
        every: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && !fun.call(scope, this[i], i, this))
                        return false;
                    ++i;
                }
                return true;
            }
            return null;
        },
        forEach: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
            }
            return this;
        },
        indexOf: function(what, i){
            i= i || 0;
            var L= this.length;
            while(i< L){
                if(this[i]=== what)
                    return i;
                ++i;
            }
            return -1;
        },
        lastIndexOf: function(what, i){
            var L= this.length;
            i= i || L-1;
            if(isNaN(i) || i>= L)
                i= L-1;
            else
                if(i< 0) i += L;
            while(i> -1){
                if(this[i]=== what)
                    return i;
                --i;
            }
            return -1;
        },
        map: function(fun, scope){
            var L= this.length, A= Array(this.length), i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        A[i]= fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
                return A;
            }
        },
        some: function(fun, scope){
            var i= 0, L= this.length;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && fun.call(scope, this[i], i, this))
                        return true;
                    ++i;
                }
                return false;
            }
        }
    }
    for(p in p2){
        if(!ap[p])
            ap[p]= p2[p];
    }
    return true;
})();

答案 6 :(得分:63)

使用while循环...

var i=0, item, items = ['one','two','three'];
while(item = items[i++]){
    console.log(item);
}

日志:'一个','两个','三个'

对于相反的顺序,一个更有效的循环

var items = ['one','two','three'], i = items.length;
while(i--){
    console.log(items[i]);
}

日志:'三','二','一'

或经典的for循环

var items = ['one','two','three']
for(var i=0, l = items.length; i < l; i++){
    console.log(items[i]);
}

日志:'一个','两个','三个'

参考: http://www.sitepoint.com/google-closure-how-not-to-write-javascript/

答案 7 :(得分:55)

简介

自从我上大学以来,我编写了Java,JavaScript,Pascal,ABAP,PHP,Progress 4GL,C / C ++以及其他一些我现在想不到的语言。< / p>

虽然他们都有自己的语言特质,但每种语言都有许多相同的基本概念。这些概念包括过程/函数,IF - 语句,FOR - 循环和WHILE - 循环。

传统的for - 循环

传统的for循环有三个组成部分:

  1. 初始化:在第一次执行外观块之前执行
  2. 条件:每次执行循环块之前都会检查一个条件,如果为false则退出循环
  3. 每次执行循环块后都会执行
  4. 这三个组件通过;符号相互分隔。这三个组件中的每个组件的内容都是可选的,这意味着以下是可能的最小for循环:

    for (;;) {
        // Do stuff
    }
    

    当然,您需要在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);
    }
    

    无论哪种效果最好,主要取决于个人品味和您正在实施的具体用例。

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

    A while循环

    for循环的一种替代方法是while循环。要循环遍历数组,您可以这样做:

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

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

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

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

    For...infor...of

    在JavaScript中,您也可以这样做:

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

    但是,这应该谨慎使用,因为它在所有情况下都不像传统的for循环那样,并且存在需要考虑的潜在副作用。有关详细信息,请参阅 Why is using "for...in" with array iteration a bad idea?

    作为for...in的替代方案,现在还有for...of。以下示例显示了for...of循环和for...in循环之间的区别:

    var 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); // logs 3, 5, 7
    }
    

    此外,您需要考虑没有版本的Internet Explorer支持for...ofEdge 12+确实如此),并且for...in至少需要Internet Explorer 10。

    Array.prototype.forEach()

    for - 循环的替代方法是Array.prototype.forEach(),它使用以下语法:

    myArray.forEach(function(value, key, myArray) {
        console.log(value);
    });
    
    所有现代浏览器以及Internet Explorer 9及更高版本都支持

    Array.prototype.forEach()

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

    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);
    });
    

答案 8 :(得分:37)

如果您想要一种简洁的方法来编写快速循环,您可以反向迭代:

for (var i=myArray.length;i--;){
  var item=myArray[i];
}

这样可以缓存长度(类似于for (var i=0, len=myArray.length; i<len; ++i),而不像for (var i=0; i<myArray.length; ++i)),同时输入的字符更少。

甚至有些时候您应该反向迭代,例如在迭代过程中计划从DOM中删除项目的live NodeList上进行迭代时。

答案 9 :(得分:29)

在JavaScript中以函数式编程方式循环数组的一些用例:

1。只需遍历一个数组

const myArray = [{x:100}, {x:200}, {x:300}];

myArray.forEach((element, index, array) => {
    console.log(element.x); // 100, 200, 300
    console.log(index); // 0, 1, 2
    console.log(array); // same myArray object 3 times
});

注意:严格来说,Array.prototype.forEach()不是一种功能方式,因为它作为输入参数所用的函数不应该返回一个值,因此不能将其视为纯函数。

2。检查数组中的任何元素是否通过了测试

const people = [
    {name: 'John', age: 23}, 
    {name: 'Andrew', age: 3}, 
    {name: 'Peter', age: 8}, 
    {name: 'Hanna', age: 14}, 
    {name: 'Adam', age: 37}];

const anyAdult = people.some(person => person.age >= 18);
console.log(anyAdult); // true

3。转换为新数组

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => element.x);
console.log(newArray); // [100, 200, 300]

注意:map()方法创建一个新数组,其结果是在调用数组中的每个元素上调用提供的函数。

4。总结一个特定的属性,并计算其平均值

const myArray = [{x:100}, {x:200}, {x:300}];

const sum = myArray.map(element => element.x).reduce((a, b) => a + b, 0);
console.log(sum); // 600 = 0 + 100 + 200 + 300

const average = sum / myArray.length;
console.log(average); // 200

5。根据原始数组创建一个新数组但不修改它

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => {
    return {
        ...element,
        x: element.x * 2
    };
});

console.log(myArray); // [100, 200, 300]
console.log(newArray); // [200, 400, 600]

6。计算每个类别的数量

const people = [
    {name: 'John', group: 'A'}, 
    {name: 'Andrew', group: 'C'}, 
    {name: 'Peter', group: 'A'}, 
    {name: 'James', group: 'B'}, 
    {name: 'Hanna', group: 'A'}, 
    {name: 'Adam', group: 'B'}];

const groupInfo = people.reduce((groups, person) => {
    const {A = 0, B = 0, C = 0} = groups;
    if (person.group === 'A') {
        return {...groups, A: A + 1};
    } else if (person.group === 'B') {
        return {...groups, B: B + 1};
    } else {
        return {...groups, C: C + 1};
    }
}, {});

console.log(groupInfo); // {A: 3, C: 1, B: 2}

7。根据特定条件

检索数组的子集
const myArray = [{x:100}, {x:200}, {x:300}];

const newArray = myArray.filter(element => element.x > 250);
console.log(newArray); // [{x:300}] 

注意:filter()方法创建一个新数组,其中包含通过所提供函数实现的测试的所有元素。

8。对数组进行排序

const people = [
  { name: "John", age: 21 },
  { name: "Peter", age: 31 },
  { name: "Andrew", age: 29 },
  { name: "Thomas", age: 25 }
];

let sortByAge = people.sort(function (p1, p2) {
  return p1.age - p2.age;
});

console.log(sortByAge);

enter image description here

9。在数组中查找元素

const people = [ {name: "john", age:23},
                {name: "john", age:43},
                {name: "jim", age:101},
                {name: "bob", age:67} ];

const john = people.find(person => person.name === 'john');
console.log(john);

enter image description here

Array.prototype.find()方法返回数组中第一个满足提供的测试函数的元素的值。

参考

答案 10 :(得分:27)

有一种方法可以做到这一点,你的循环中只有很少的隐式范围,并且不需要额外的变量。

var i = 0,
     item;

// note this is weak to sparse arrays or falsey values
for ( ; item = myStringArray[i++] ; ){ 
    item; // This is the string at the index.
}

或者如果你真的想获得id并且有一个非常经典的for循环:

var i = 0,
    len = myStringArray.length; // cache the length

for ( ; i < len ; i++ ){
    myStringArray[i]; // Don't use this if you plan on changing the length of the array
}

现代浏览器都支持迭代器方法forEachmapreducefilter以及Array prototype上的许多其他方法。

答案 11 :(得分:26)

在JavaScript中有各种循环数组的方法。

通用循环:

var i;
for (i = 0; i < substr.length; ++i) {
    // Do something with `substr[i]`
}

ES5&#39; forEach:

substr.forEach(function(item) {
    // Do something with `item`
});

<强> jQuery.each:

jQuery.each(substr, function(index, item) {
    // Do something with `item` (or `this` is also `item` if you like)
});

查看this了解详细信息,或者您也可以查看MDN以在JavaScript和&amp ;;中循环播放数组。使用jQuery检查jQuery for each

答案 12 :(得分:25)

我完全建议使用underscore.js库。它为您提供了各种可用于迭代数组/集合的函数。

例如:

_.each([1, 2, 3], function(num){ alert(num); });
=> alerts each number in turn...

答案 13 :(得分:24)

数组循环:

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

对象循环:

for(var prop in obj){
    var propValue = obj[prop];
    console.log(propValue);
}

答案 14 :(得分:22)

是的,您可以在JavaScript中使用循环执行相同的操作,但不限于此,在JavaScrip中执行循环数组的许多方法,假设您在下面有这个数组,并且您想对它进行循环:< / p>

var arr = [1, 2, 3, 4, 5];

这些是解决方案:

1)For loop

For循环是在JavaScript中循环遍历数组的常用方法,但不被认为是大型数组的最快解决方案:

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

2)while loop

while循环被认为是循环遍历长数组的最快方法,但通常在JavaScript中使用较少:

let i=0;

while (arr.length>i) {
    console.log(arr[i]);
    i++;
}

3)一边做什么
做同样的事情同时使用一些语法差异如下:

let i=0;
do {
  console.log(arr[i]);
  i++;
}
while (arr.length>i);

这些是进行javascript循环的主要方法,但还有更多方法可以做到这一点。

我们还使用for in循环来循环javascript中的对象。

另请参阅JavaScript中的Array上的map()filter()reduce()等函数。与使用whilefor相比,他们可以做得更快更好。

如果您想了解有关JavaScript中数组的异步函数的更多信息,那么这篇文章很好。

  

功能性编程一直引起轰动   发展世界这些天。并且有充分理由:功能性   技术可以帮助您编写更容易的更多声明性代码   理解,重构和测试。

     

功能编程的基石之一是它的特殊用途   列表和列表操作。那些东西正是如此   听起来像是:事物的数组,以及你对它们所做的事情。   但是功能性思维对待它们的方式与你有所不同   可能会期待。

     

本文将仔细研究一下我所谓的“大”   三个“列表操作:映射,过滤和减少。包裹你的头脑   围绕这三个功能是迈向能力的重要一步   编写干净的功能代码,并打开大门   强大的功能和反应式编程技术。

     

这也意味着你永远不必再写一个for循环。

了解更多&gt;&gt; here

答案 15 :(得分:20)

如果有人对可用于数组迭代的多种机制的性能方面感兴趣 ,我已经准备了以下JSPerf测试:

https://jsperf.com/fastest-array-iterator

Performamce results

结果:

传统的for()迭代器是迄今为止最快的方法,特别是与缓存的数组长度一起使用时。

let arr = [1,2,3,4,5];

for(let i=0, size=arr.length; i<size; i++){
    // do something
}

Array.prototype.forEach()Array.prototype.map()方法是最慢的近似值,可能是由于函数调用开销

答案 16 :(得分:19)

如果您正在使用jQuery库,请考虑使用 http://api.jquery.com/jQuery.each/

来自文档:

  

jQuery.each( collection, callback(indexInArray, valueOfElement) )

     

返回: 对象

     

描述: 一个通用的迭代器函数,可用于   无缝迭代对象和数组。数组和数组   具有length属性的对象(例如函数的arguments对象)   由数字索引迭代,从0到length-1。其他对象是   通过其命名属性进行迭代。

     

$.each()功能与$(selector).each()不同,即{}   用于独占迭代jQuery对象。 $.each()   函数可用于迭代任何集合,无论它是否为   map(JavaScript对象)或数组。在数组的情况下,   回调传递一个数组索引和相应的数组值   时间。 (也可以通过this关键字访问该值,但是   Javascript将始终将this值包装为Object,即使它是。{   一个简单的字符串或数字值。)该方法首先返回它   参数,迭代的对象。

答案 17 :(得分:16)

我还没有看到这种变化,我个人最喜欢这种变化:

给定一个数组:

var someArray = ["some", "example", "array"];

您可以在不访问length属性的情况下遍历它:

for (var i=0, item; item=someArray[i]; i++) {
  // item is "some", then "example", then "array"
  // i is the index of item in the array
  alert("someArray[" + i + "]: " + item);
}

见这个JsFiddle证明:http://jsfiddle.net/prvzk/

这仅适用于稀疏的数组。这意味着数组中的每个索引实际上都有一个值。但是,我发现在实践中我几乎没有在Javascript中使用稀疏数组......在这种情况下,使用对象作为map / hashtable通常要容易得多。如果你确实有一个稀疏数组,并希望循环遍历0 .. length-1,你需要for(var i = 0; i&lt; someArray.length; ++ i)构造,但是你仍需要一个if循环检查当前索引处的元素是否实际定义。

另外,正如CMS在下面的评论中提到的那样,您只能在不包含任何伪造值的数组上使用它。示例中的字符串数组有效,但如果您有空字符串,或者数字为0或NaN等,则循环将过早中断。再次在实践中,这对我来说几乎不是一个问题,但是要记住这一点,这使得在使用它之前需要考虑这个循环......这可能会使某些人丧失资格:)

我喜欢这个循环:

  • 写的时间很短
  • 无需访问(更不用说缓存)长度属性
  • 要在环路中自动定义要访问的项目 你选择的名字下的身体。
  • 非常自然地与array.push和array.splice结合使用数组,如list / stacks

这个工作的原因是数组规范要求当你从索引&gt; =数组的长度读取一个项目时,它将返回undefined。当您写到这样的位置时,它实际上会更新长度。

对我来说,这个结构最接近地模仿我喜欢的Java 5语法:

for (String item : someArray) {
}

...还有了解循环中当前索引的附加好处

答案 18 :(得分:14)

最优雅,最快捷的方式

var arr = [1, 2, 3, 1023, 1024];
for (var value; value = arr.pop();) {
    value + 1
}

http://jsperf.com/native-loop-performance/8


编辑(因为我错了)


比较循环遍历100000个项目数组的方法,并每次使用新值进行最小化操作。

<强>制备

<script src="//code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js"></script>
<script>
    Benchmark.prototype.setup = function() {
        // Fake function with minimal action on the value
        var tmp = 0;
        var process = function(value) {
            tmp = value; // Hold a reference to the variable (prevent engine optimisation?)
        };

        // Declare the test Array
        var arr = [];
        for (var i = 0; i < 100000; i++)
            arr[i] = i;
    };
</script>

<强>试验:

<a href="http://jsperf.com/native-loop-performance/16" 
   title="http://jsperf.com/native-loop-performance/16"
><img src="http://i.imgur.com/YTrO68E.png" title="Hosted by imgur.com" /></a>

答案 19 :(得分:14)

有一种方法只迭代自己的对象属性,不包括原型的属性:

for (var i in array) if (array.hasOwnProperty(i)) {
    // do something with array[i]
}

但它仍将迭代自定义属性。

在javascript中,任何自定义属性都可以分配给任何对象,包括数组。

如果想要对已解析的数组进行迭代,则应使用for (var i = 0; i < array.length; i++) if (i in array)array.forEach es5shim

答案 20 :(得分:14)

在JavaScript中有两种方法可以做到这一点。前两个示例是JavaScript示例。第三个使用JavaScript库,即jQuery使用.each()函数。

var myStringArray = ["hello", "World"];
for(var i in myStringArray) {
  alert(myStringArray[i]);
}

var myStringArray = ["hello", "World"];
for (var i=0; i < myStringArray.length; i++) {
  alert(myStringArray[i]);
}

var myStringArray = ["hello", "World"];
$.each(myStringArray, function(index, value){
  alert(value);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

答案 21 :(得分:10)

优化的方法是缓存数组的长度,并使用单个var模式使用单个var关键字初始化所有变量。

var i, max, myStringArray = ["Hello","World"];
for (i = 0, max = myStringArray.length; i < max; i++) {
    alert(myStringArray[i]);
   //Do something
}

如果迭代次序无关紧要,你应该尝试反向循环,它是最快的,因为它减少了开销条件测试和减少在一个语句中:

var i,myStringArray = ["item1","item2"];
for (i =  myStringArray.length; i--) {
    alert(myStringArray[i]);
}
循环时使用

或更好更清洁:

var myStringArray = ["item1","item2"],i = myStringArray.length;
while(i--) {
   // do something with fruits[i]
}

答案 22 :(得分:10)

在JavaScript中,有很多解决方案来循环数组。

以下代码是受欢迎的代码

&#13;
&#13;
/** Declare inputs */
const items = ['Hello', 'World']

/** Solution 1. Simple for */
console.log('solution 1. simple for')

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

console.log()
console.log()

/** Solution 2. Simple while */
console.log('solution 2. simple while')

let i = 0
while (i < items.length) {
  console.log(items[i++])
}

console.log()
console.log()

/** Solution 3. forEach*/
console.log('solution 3. forEach')

items.forEach(item => {
  console.log(item)
})

console.log()
console.log()

/** Solution 4. for-of*/
console.log('solution 4. for-of')

for (const item of items) {
  console.log(item)
}

console.log()
console.log()
&#13;
&#13;
&#13;

答案 23 :(得分:9)

我认为最好的方法是使用Array.forEach函数。如果您不能使用我建议从MDN获取polyfill使我可用,它肯定是在JavaScript中迭代数组的最安全的方法。

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

正如其他人所说,这几乎总是你想要的:

var numbers = [1,11,22,33,44,55,66,77,88,99,111];
var sum = 0;
numbers.forEach(function(n){
  sum += n;
});

这可确保您在处理数组范围内所需的任何内容都保持在该范围内,并且您只处理数组的值,而不是对象属性和其他成员,这就是.. in。

在大多数情况下使用常规c样式for循环工作,重要的是要记住循环中的所有内容与程序的其余部分共享它的范围,{}不会创建新范围。

因此:

var sum = 0;
var numbers = [1,11,22,33,44,55,66,77,88,99,111];

for(var i = 0; i<numbers.length; ++i){ 
  sum += numbers[i];
}

alert(i);

将输出“11” - 这可能是您想要的,也可能不是。

工作jsFiddle示例: https://jsfiddle.net/workingClassHacker/pxpv2dh5/7/

答案 24 :(得分:9)

简短回答:是的。你可以这样做:

var myArray = ["element1", "element2", "element3", "element4"];

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

在浏览器控制台中,您可以看到类似&#34; element1&#34;,&#34; element2&#34;等等。

答案 25 :(得分:8)

如果你想使用jQuery,它的文档中有一个很好的例子:

 $.each([ 52, 97 ], function( index, value ) {
      alert( index + ": " + value );
 });

答案 26 :(得分:8)

例如,我在Firefox控制台中使用:

[].forEach.call(document.getElementsByTagName('pre'), function(e){ 
   console.log(e);
})

答案 27 :(得分:8)

var x = [4, 5, 6];
for (i = 0, j = x[i]; i < x.length; j = x[++i]) {
    console.log(i,j);
}

更干净......

答案 28 :(得分:7)

只是一个简单的单行解决方案

arr = ["table", "chair"];

// solution
arr.map((e) => {
  console.log(e);
  return e;
});

答案 29 :(得分:7)

它不是100%相同,但相似:

   var myStringArray = ['Hello', 'World']; // array uses [] not {}
    for (var i in myStringArray) {
        console.log(i + ' -> ' + myStringArray[i]); // i is the index/key, not the item
    }

答案 30 :(得分:6)

数组迭代有4种方式:

// 1: for

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

// 2: forEach

arr.forEach((v, i) => console.log(v));

// 3: for in

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

// 4: for of

for (const v of arr) {
  console.log(v);
}

总结:1 和 3 解决方案创建额外的变量,2 - 创建额外的函数上下文。最好的方法是第四个——“for of”。

答案 31 :(得分:6)

当然它效率低下而且很多人鄙视它,但它是最接近提到的那个之一:

var myStringArray = ["Hello","World"];
myStringArray.forEach(function(f){
    // Do something
})

答案 32 :(得分:5)

嗯,这个怎么样:

for (var key in myStringArray) {
    console.log(myStringArray[key]);
}

答案 33 :(得分:5)

似乎除lodash之外的forEach列出了所有变体:

_.forEach([1, 2], (value) => {
  console.log(value);
});

答案 34 :(得分:5)

var myStringArray = ["hello", "World"];
myStringArray.forEach(function(val, index){
   console.log(val, index);
})

答案 35 :(得分:4)

摘要:

在数组上进行迭代时,我们通常希望实现以下目标之一:

  1. 创建一个新的数组,保留原样:使用Tuple
  2. 对每个数组元素/在每个数组元素上执行操作,并可能使数组发生变化:使用map()for..of或常规for循环

示例:

forEach()

要使用哪个?

在大多数情况下,它并不重要。但是,在某些情况下,一种迭代类型可能更适合您的需求:

  1. 当您要操作数组但保留完整的旧数组(例如函数编程)时,最好使用const arr1 = [1, 2, 3]; const arr2 = arr1.map(el => el * 2); // with map we create a new arr2, arr1 is left untouched console.log(arr2, arr1); // regular for loop for (let i = 0; i < arr1.length; i++) { console.log(arr1[i]); } console.log('\n'); // for of loop for (let el of arr1) { console.log(el); } console.log('\n'); // forEach() arr1.forEach(el => { console.log(el) })进行迭代。当您不需要返回新数组时,请不要使用map()map()在所有循环方法中性能最慢。
  2. 当性能发挥作用时,当您需要大量迭代时,可以使用常规的for循环:

map()

通常(由于JS引擎的不同而有所不同)具有最佳性能,因为它是最“低级”的迭代形式。

答案 36 :(得分:4)

您可以通过多种不同的方法遍历数组。我已经把我最喜欢的方法从上到下排序了。

1.使用 for loop

如果只是简单地遍历数组,for 循环是我的首选。

let array = [1, 2, 3, 4, 5];
for (let i = 0; i < array.length; i++) {
  console.log(array[i]);
}

2.使用 forEach 循环

forEach 循环是循环数组的一种现代方式。此外,它为数组和元素提供了更大的灵活性和控制权。

let array = [1, 2, 3, 4, 5];
array.forEach((element) => {
  console.log(element);
});

3.使用 for...of

for...of 循环让您可以直接访问数组元素。

let array = [1, 2, 3, 4, 5];
for (let element of array) {
  console.log(element);
}

4.使用 for...in 循环

for...in 为您提供了一个可以访问数组元素的键。

let array = [1, 2, 3, 4, 5];
for(let index in array){
  console.log(array[index]);
}

5.使用while循环

while loop 也可用于遍历数组。

let array = [1, 2, 3, 4, 5];
let length = array.length;
while(length > 0){
  console.log(array[array.length - length]);
  length--;
}

6.使用 do...while 循环

同样,我使用 do...while 循环

let array = [1, 2, 3, 4, 5];
let length = array.length;
do {
  console.log(array[array.length - length]);
  length--;
}
while (length > 0)

答案 37 :(得分:4)

JavaScript中的数组遍历速查表

给出数组,您可以按以下多种方式之一遍历它。

1。经典的for循环

const myArray = ['Hello', 'World'];

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

2。 for...of

const myArray = ['Hello', 'World'];

for (const item of myArray) {
  console.log(item);
}

3。 Array.prototype.forEach()

const myArray = ['Hello', 'World'];

myArray.forEach(item => {
  console.log(item);
});

4。 while循环

const myArray = ['Hello', 'World'];
let i = 0;

while (i < myArray.length) {
  console.log(myArray[i]);
  i++;
}

5。 do...while循环

const myArray = ['Hello', 'World'];
let i = 0;

do {
  console.log(myArray[i]);
  i++;
} while (i < myArray.length);

6。队列样式

const myArray = ['Hello', 'World'];


while (myArray.length) {
  console.log(myArray.shift());
}

7。堆叠样式

注意:该列表在此列表中反印。

const myArray = ['Hello', 'World'];

while (myArray.length) {
  console.log(myArray.pop());
}

答案 38 :(得分:4)

有几种遍历数组的方法: 您的平均for循环次数

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

while循环:

const array = [1, 2, 3, 4];
let i = 0;
while (i < array.length) {
  console.log(array[i]); // Should log 1 then 2 then 3 then 4
  i++;
}

forEach循环:

const array = [1, 2, 3, 4];
array.forEach(value => {
  console.log(value); // Should log 1 then 2 then 3 then 4
});

我之所以不使用.map是因为.map主要用于更改数组的值。

答案 39 :(得分:4)

您可以使用Array.prototype.forEach(...)

var arr = ["apple", "banana", "cherry", "mango"];
arr.forEach((item, index)=>{
   //Some code...
});

Array.prototype.forEach(...)

var arr = ["apple", "banana", "cherry", "mango"];
arr.map((item, index)=>{
   //Some code...
});

或者前面提到的jquery或for循环方式。

答案 40 :(得分:4)

最好使用顺序for循环:

for (var i = 0; i < myStringArray.length; i++) {
    // Do something
}

答案 41 :(得分:3)

有多种方法可以迭代JavaScript数组:

  • while

  • for循环

  • for

  • for

  • forEach()方法

  • map()方法

let arr = [10, 20, 30];
let len = arr.length;

var i = 0;
while (value = arr[i++])
  console.log(value);

for (let i = 0; i < len; i++)
  console.log(arr[i]);

for (let i of arr)
  console.log(i);

for (let i in arr)
  console.log(arr[i]);

arr.forEach(item => console.log(item))

arr.map(item => console.log(item))

答案 42 :(得分:3)

var obj = ["one","two","three"];

for(x in obj){
    console.log(obj[x]);
}

答案 43 :(得分:1)

var array = ['hai', 'hello', 'how', 'are', 'you']
$(document).ready(function () {
  $('#clickButton').click(function () {
    for (var i = 0; i < array.length; i++) {
      alert(array[i])
    }
  })
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<input id="clickButton" value="click Me" type="button"/>
<div id="show"></div>

答案 44 :(得分:1)

//Make array
var array = ["1","2","3","4","5","6","7","8","9","10"]
//Loop
for(var i = 0; i < array.length; i++){
 console.log((i+1) + " --> " + array[i])
}

对于i的ACTUAL编号,如果需要,您需要将(i+1)更改为i(i)
希望这会有所帮助。

答案 45 :(得分:0)

应避免递归遍历数组,因为它会触发堆栈溢出。不同的浏览器也具有不同的堆栈大小。

const data = ['one', 'two', 'three']

const loop = (items, index=0) => {
  if (items.length === index) {
    return;
  }
  console.log(items[index], index)
  loop(items, index+=1)
}

loop(data)

答案 46 :(得分:0)

深奥的可变方式

let a= ["Hello", "World"];

while(a.length) { console.log( a.shift() ); }