javascript中的数组循环

Loop through an array in JavaScript

在爪哇中,可以使用EDCOX1×0循环来遍历数组中的对象,如下:

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

在javascript中也可以这样做吗?


使用顺序for循环:

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

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

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

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

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

例如:

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

上述代码将控制"A"、"B"、"C"和"foo!".

如果您使用一些严重依赖于本机原型扩充的库(例如moooltools),这将是一个特别的问题。

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

1
2
3
4
5
6
7
8
9
10
11
12
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方法只允许枚举自己的属性,也就是说,只枚举对象物理上具有的属性,而不枚举继承的属性。

我建议您阅读以下文章:

  • 枚举与迭代


是的,假设您的实现包括ecmascript 2015中引入的forof功能("和谐"版本)。这是目前相当安全的假设。好的。

工作原理如下:好的。

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

或者更好的是,由于ecmascript 2015还通过letconst提供了块范围变量:好的。

1
2
3
4
5
6
// 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,还是只处理实际存在的元素?这两种方法都有大量的应用程序;这取决于您使用阵列的目的。好的。

如果使用for..of迭代数组,则循环体将执行length次,对于数组中实际不存在的任何项,循环控制变量将设置为undefined。根据"用代码做点什么"的细节,这种行为可能是您想要的,但是如果这不是您想要的,您应该使用不同的方法。好的。

当然,有些开发人员别无选择,只能使用不同的方法,因为不管出于什么原因,他们的目标是一个尚不支持forof的javascript版本。好的。

只要您的javascript实现符合先前版本的ecmascript规范(例如,9之前的Internet Explorer版本除外),那么您就可以使用forEach迭代器方法而不是循环。在这种情况下,您需要传递一个函数来对数组中的每个项进行调用:好的。

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

forof不同,forEach只调用实际包含值的元素的函数。如果用三个元素和248个长度传递我们的假设数组,它将只调用函数三次,而不是248次。它还区分丢失的元素和实际设置为undefined的元素;对于后者,它仍然调用函数,将undefined作为参数传递。如果这是处理稀疏数组的方式,那么即使您的解释器支持forof.forEach也可能是解决问题的方法。好的。

最后一个选项是一个显式的计数循环,它适用于所有版本的javascript。您只需将长度从0算到1,并使用计数器作为索引。基本循环如下:好的。

1
2
3
4
5
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..of。如果您只想处理稀疏数组中实际存在的元素,如.forEach,可以在索引上添加一个简单的in测试:好的。

1
2
3
4
5
6
7
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 ...
  }
}

将长度值赋给局部变量(而不是在循环条件中包含完整的myStringArray.length表达式)可以显著提高性能,因为它每次都跳过一个属性查找;在我的机器上使用rhino,加速率为43%。好的。

您可以在loop initialization子句中看到长度缓存,如下所示:好的。

1
2
var i, len, myStringArray = ["Hello","World" ];
for (len = myStringArray.length, i=0; i<len; ++i) {

for...in语法,这些方法是通过他人的链过的对象的性质;从阵列中的JavaScript是安安是面向与numeric性质的名称(和安-自动更新的length性质),你可以theoretically过安环阵列与她。但问题是,它不restrict T本身的性质numeric值(记得那夜的方法是真的是谁的属性值是一个闭合的),或是它的guaranteed遍历过的那些在数值的顺序。因此,在for...in语法应不被用于链通翼。

/好的。 好的。


您可以使用map,这是一种功能性编程技术,也可以在其他语言(如python和haskell)中使用。

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

一般的语法是:

1
array.map(func)

一般情况下,func将采用一个参数,该参数是数组的一个项。但对于javascript,它可以采用第二个参数(即项的索引)和第三个参数(即数组本身)。

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

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

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

您不必以内联方式编写函数。它可以是一个单独的函数。

1
2
3
4
5
var item_processor = function(item) {
      // Do something complicated to an item
}

new_list = my_list.map(item_processor);

相当于:

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

除非你没有得到new_list


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

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

它也进行了优化("缓存"数组长度)。如果你想了解更多,请阅读我关于这个主题的文章。


(是的mystringarray){

(你自愿直接的问题:现在你可以!)

大多数其他的答案是对的,但他们没有提到(为本书写),ECMA脚本执行<6> ; ;< > 2015年冰/履约bringing机制做一个新的迭代,for..of回路。

这种新的语法是最优雅的方式在两个数组进行迭代的JavaScript(As Long,你不需要迭代的指标,但它没有冰的browsers widely负载。

它与现有的工厂13 + Firefox,Chrome 37 +和它不可以工作与其他browsers(见下面的浏览器兼容性)。我们要做的luckily编译器(如巴别塔),允许我们使用的下一代,今天的特征。

它也制造厂(ASON节点测试网络的在线版本0.12.0)。

迭代的阵列

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

迭代的目标阵列

1
2
3
4
5
6
7
8
var band = [
  {firstName : 'John', lastName: 'Lennon'},
  {firstName : 'Paul', lastName: 'McCartney'}
];

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

A:迭代的发电机

(例如,从中提取developer.mozilla.org https:/ / /美国/文件/网站/脚本/参考/报表/对…)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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表/ es6 / #为..of环

规格:http:/ / / doku.php wiki.ecmascript.org吗?id =和谐:迭代器

}


Opera、Safari、Firefox和Chrome现在都共享一组增强的数组方法来优化许多公共循环。

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

Mozilla实验室发布了他们和Webkit都使用的算法,这样你就可以自己添加它们。

筛选器返回满足某些条件或测试的项数组。

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

如果有人通过测试,有些人会返回true。

foreach对每个数组成员运行函数,不返回任何内容。

map与for each类似,但它为每个元素返回一个操作结果数组。

这些方法都将一个函数作为第一个参数,并有一个可选的第二个参数,这是一个对象,当数组成员循环通过函数时,您希望将其作用域强加于该对象。

忽略它直到你需要它。

indexof和last indexof查找与其参数完全匹配的第一个或最后一个元素的适当位置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
(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;
})();


使用while循环…

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

日志:"1"、"2"、"3"

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

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

日志:"三"、"二"、"一"

或者经典的for循环

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

日志:"1"、"2"、"3"

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


简介

自从我在大学的时候,我已经编程了Java、JavaScript、Pascal、ABAP、PHP、进度4GL、C/C++等可能还有一些我现在无法想象的语言。

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

传统的FOR循环

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

  • 初始化:在第一次执行look块之前执行
  • 条件:每次执行循环块之前检查一个条件,如果为false,则退出循环。
  • Afterthought:每次执行循环块后执行
  • 这三个组件通过;符号相互分离。这三个组件中的每一个的内容都是可选的,这意味着以下内容是尽可能少的FOR循环:

    1
    2
    3
    for (;;) {
        // Do stuff
    }

    当然,您需要在该FOR循环中的某个地方包含一个if(condition === true) { break; }或一个if(condition === true) { return; },以使它停止运行。

    但是,通常,初始化用于声明索引,条件用于将该索引与最小值或最大值进行比较,Afterthought用于增加索引:

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

    使用传统的FOR循环在数组中循环

    通过数组循环的传统方法是:

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

    或者,如果您喜欢向后循环,可以这样做:

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

    然而,有许多可能的变化,例如这个:

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

    …或者这个…

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

    …或者这个:

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

    无论哪种方法最有效,在很大程度上都取决于个人品味和您正在实现的特定用例。

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

    一个WHILE循环

    FOR循环的另一种选择是WHILE循环。要循环遍历数组,可以执行以下操作:

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

    与传统的FOR循环一样,甚至最老的浏览器也支持WHILE循环。

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

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

    For...infor...of

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

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

    但是,使用时应小心,因为它与传统的FOR循环在所有情况下的行为都不同,并且需要考虑潜在的副作用。明白为什么在数组迭代中使用"for…in"是个坏主意吗?了解更多详细信息。

    作为For...in的替代品,现在也有for...of的替代品。下面的示例显示了for...of循环和For...in循环之间的区别:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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...of(EDGE 12+支持),并且For...in至少需要Internet Explorer 10。

    Array.prototype.forEach()

    FOR循环的另一种选择是Array.prototype.forEach()循环,它使用以下语法:

    1
    2
    3
    myArray.forEach(function(value, key, myArray) {
        console.log(value);
    });

    所有现代浏览器以及Internet Explorer 9及更高版本都支持Array.prototype.forEach()

    图书馆

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

    jQuery.each(),jquery中:

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

    _.each(),下划线.js:

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

    _.forEach(),在lodash.js中:

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

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

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

    这样做的好处是缓存长度(与for (var i=0, len=myArray.length; i类似,与for (var i=0; i不同),同时输入的字符更少。

    甚至有些时候,您应该反向迭代,比如在活动节点列表上迭代时,您计划在迭代期间从DOM中删除项目。


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

    1。只需在数组中循环

    1
    2
    3
    4
    5
    6
    7
    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。检查数组中的任何元素是否通过测试

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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

    三。转换为新数组

    1
    2
    3
    4
    const myArray = [{x:100}, {x:200}, {x:300}];

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

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

    4。对一个特定属性求和,并计算其平均值

    1
    2
    3
    4
    5
    6
    7
    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。基于原始数组创建新数组,但不修改它

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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。计算每个类别的数量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    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。基于特定条件检索数组的子集

    1
    2
    3
    4
    const myArray = [{x:100}, {x:200}, {x:300}];

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

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

    8。排序数组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    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。在数组中查找元素

    1
    2
    3
    4
    5
    6
    7
    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.some()。
    • array.prototype.foreach()。
    • array.prototype.map()。
    • array.prototype.filter()。
    • array.prototype.sort()。
    • 扩展句法
    • array.prototype.find()。

    有一种方法可以做到这一点,即循环中的隐式作用域非常小,并且去掉了多余的变量。

    1
    2
    3
    4
    5
    6
    7
    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循环:

    1
    2
    3
    4
    5
    6
    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以及数组原型上的许多其他方法。


    有不同的方式在两个环通JavaScript数组。

    通用的循环:

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

    es5的foreach:

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

    :jQuery.each

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

    看,这有一个对的详细信息,或者你也可以在支票薄链通过JavaScript数组在使用jQuery &;检查jQuery简化。


    我会彻底推荐使用underline.js库。它为您提供了各种可用于在数组/集合上迭代的函数。

    例如:

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


    数组循环:

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

    对象循环:

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


    是的,您可以在JavaScript中使用循环(但不仅限于此)执行相同的操作,在JavaStrip中有许多方法可以循环数组,假设下面有这个数组,并且您希望对它执行循环:

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

    这些是解决方案:

    1)for循环

    for循环是在javascript中通过数组循环的一种常见方法,但不被认为是大型数组的最快解决方案:

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

    2)while循环

    虽然loop被认为是通过长数组进行循环的最快方法,但通常在javascript中使用较少:

    1
    2
    3
    4
    5
    6
    let i=0;

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

    3)做在执行与while相同的操作时执行以下语法差异:

    1
    2
    3
    4
    5
    6
    let i=0;
    do {
      console.log(arr[i]);
      i++;
    }
    while (arr.length>i);

    这些是执行JavaScript循环的主要方法,但是还有其他方法可以做到这一点。

    另外,我们还使用for in循环来循环JavaScript中的对象。

    还可以查看javascript中数组上的map()filter()reduce()等函数。他们可能比使用whilefor做得更快更好。

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

    Functional programming has been making quite a splash in the
    development world these days. And for good reason: Functional
    techniques can help you write more declarative code that is easier to
    understand at a glance, refactor, and test.

    One of the cornerstones of functional programming is its special use
    of lists and list operations. And those things are exactly what the
    sound like they are: arrays of things, and the stuff you do to them.
    But the functional mindset treats them a bit differently than you
    might expect.

    This article will take a close look at what I like to call the"big
    three" list operations: map, filter, and reduce. Wrapping your head
    around these three functions is an important step towards being able
    to write clean functional code, and opens the doors to the vastly
    powerful techniques of functional and reactive programming.

    It also means you'll never have to write a for loop again.

    阅读更多信息>>此处:


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

    从文档中:

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

    Returns: Object

    Description: A generic iterator function, which can be used to
    seamlessly iterate over both objects and arrays. Arrays and array-like
    objects with a length property (such as a function's arguments object)
    are iterated by numeric index, from 0 to length-1. Other objects are
    iterated via their named properties.

    The $.each() function is not the same as $(selector).each(), which is
    used to iterate, exclusively, over a jQuery object. The $.each()
    function can be used to iterate over any collection, whether it is a
    map (JavaScript object) or an array. In the case of an array, the
    callback is passed an array index and a corresponding array value each
    time. (The value can also be accessed through the this keyword, but
    Javascript will always wrap the this value as an Object even if it is
    a simple string or number value.) The method returns its first
    argument, the object that was iterated.


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

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

    Performamce results

    结果:

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

    1
    2
    3
    4
    5
    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()方法是最慢的近似,可能是函数调用开销的结果。


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

    给定数组:

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

    您可以循环访问它,而不必访问长度属性:

    1
    2
    3
    4
    5
    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);
    }

    请参阅此jfiddle演示:http://jsfiddle.net/prvzkk/

    这只适用于不稀疏的数组。这意味着数组中的每个索引实际上都有一个值。然而,我发现在实践中,我很少在javascript中使用稀疏数组…在这种情况下,将对象用作映射/哈希表通常要容易得多。如果您有一个稀疏数组,并且想要循环0..length-1,您需要for(var i=0;i

    此外,正如CMS在下面的注释中提到的,您只能在不包含任何虚伪值的数组上使用它。示例中的字符串数组可以工作,但如果您有空字符串,或者数字为0或NaN等,则循环将过早中断。在实践中,这对我来说几乎从来都不是一个问题,但要记住这一点,这使得在你使用它之前要考虑这个循环…这可能会使某些人丧失资格。)

    我喜欢这个循环的原因是:

    • 写得太短了
    • 无需访问(更不用说缓存)长度属性
    • 要访问的项在循环中自动定义你选择的名字下的身体。
    • 与array.push和array.splice非常自然地结合使用列表/堆栈等数组

    这样做的原因是,数组规范要求当您从一个索引中读取一个大于等于数组长度的项时,它将返回未定义的。当你写到这样一个位置时,它实际上会更新长度。

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

    1
    2
    for (String item : someArray) {
    }

    …另外还有一个好处,就是了解循环中的当前索引


    最优雅的和固定的方式

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

    http:/ / / jsperf.com本地环路性能/ 8

    编辑(因为我是错误的)

    链比较方法通过阵列和100000的项目做一个小手术。"每一次新的价值。

    • http:/ / / / bqhed # jsben.ch

    制备:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <script src="//code.jquery.com/jquery-2.1.0.min.js">
    <script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js">

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

    测试:

    1
    2
    3
    <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" />


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

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

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

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

    如果要迭代稀疏数组,则应使用带es5shimfor (var i = 0; i < array.length; i++) if (i in array)array.forEach


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

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

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

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


    在JavaScript中,循环数组的解决方案太多了。

    下面的代码是流行代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    /** 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()


    改进的方法是缓存length of the阵列和模式是采用单变量与单initializing全是关键字。

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

    如果银行不阶迭代物比你应该试着反向回路,它是fastest AS网络开销减少空调的测试和decrement冰在一个声明:

    1
    2
    3
    4
    var i,myStringArray = ["item1","item2"];
    for (i =  myStringArray.length; i--) {
        alert(myStringArray[i]);
    }

    或更好的清洁和使用while循环:

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

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

    1
    2
    3
    4
    5
    var myArray = ["element1","element2","element3","element4"];

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

    在浏览器控制台中,您可以看到打印的"element1"、"element2"等内容。


    我认为最好的方法是使用array.foreach函数。如果您不能使用它,我建议您从MDN获取polyfill以使我可用,这无疑是在JavaScript中迭代数组的最安全的方法。

    https://developer.mozilla.org/en/docs/web/javascript/reference/global_objects/array/foreach

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

    1
    2
    3
    4
    5
    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循环是可行的,记住循环中的所有内容都与程序的其余部分共享它的作用域是非常重要的,不会创建新的作用域。

    因此:

    1
    2
    3
    4
    5
    6
    7
    8
    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"-这可能是或可能不是您想要的。

    工作jfiddle示例:https://jsfiddle.net/workingclasshacker/pxpv2dh5/7/


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

    更干净了…


    例如,在一个控制台用于Firefox:

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

    如果要使用jquery,它的文档中有一个很好的示例:

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

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

    1
    2
    3
    4
       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
        }


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

    1
    2
    3
    4
    5
    6
    7
    arr = ["table","chair"];

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


    酸性的低效和多despise它,但它的一closest的上述两个:

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


    好的,这个怎么样:

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


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

    似乎罗达什列出了除forEach以外的所有变体:

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

    最好使用顺序FOR循环:

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

    总结:

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

  • 创建一个新的数组,保持原始数组不变:使用map()
  • 对每个数组元素执行一个操作,并可能改变数组:使用for..offorEach()或常规for循环
  • 实例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    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('
    '
    );

    // for of loop
    for (let el of arr1) {
      console.log(el);

    }

    console.log('
    '
    );


    // forEach()
    arr1.forEach(el => {
      console.log(el)
    })

    用哪一个?

    大多数时候都没那么重要。但是,有一些边缘情况,其中一种类型的迭代可能更适合您的需求:

  • 当您想要操作一个数组,但保持旧数组不变(例如函数编程)时,最好使用map()进行迭代。当不需要返回新数组时,不要使用map()map()具有所有循环方法中最慢的性能。
  • 当性能发挥作用时,当需要迭代非常多的次数时,常规for循环:
  • for(let i=0; i < arr.length; i++) {}

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


    1
    2
    3
    4
    5
    var obj = ["one","two","three"];

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

    循环遍历数组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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)


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