javascript - 遍历JavaScript中的数组

标签 javascript arrays loops for-loop

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

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


您可以在JavaScript中做同样的事情吗?

最佳答案

您有几种选择:

1.顺序for循环:



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





优点


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


缺点


太冗长
势在必行
容易出现off-by-one errors(有时也称为围栏发布错误)


2. Array.prototype.forEach

ES5规范引入了许多有益的数组方法,其中之一是Array.prototype.forEach,它为我们提供了一种遍历数组的简洁方法:



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





ES5规范发布时(截至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 });


地图的正确使用案例:



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

console.log(doubled);





同样,例如,如果您尝试将数组缩小为一个值,则想对数字数组求和,则应使用reduce方法。

反模式:

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


正确使用减少:



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语句。

该语句适用于任何类型的可迭代对象,也适用于生成器(任何具有[Symbol.iterator]属性的对象)。

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

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


优点


它可以遍历各种各样的对象。
可以使用普通的流控制语句(break / continue)。
对迭代串行异步值很有用。


缺点


如果您以较旧的浏览器为目标,则编译后的输出might surprise you


不要使用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方法仅允许您枚举自己的属性,仅枚举对象物理上具有的属性,而没有枚举属性。

我建议您阅读以下文章:


Enumeration VS Iteration

关于javascript - 遍历JavaScript中的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35794447/

相关文章:

java - 为什么我的循环只运行一次?

c++ - 程序不等待 cin

javascript - 如何保持 Javascript 数组排序,而不对其进行排序

javascript - 在materializecss中,如何从右侧而不是默认左侧打开滑出菜单?

javascript - 如何设置选择元素的选定选项而不触发更改事件?

javascript - 在特定的 Google Chrome 选项卡上执行 javascript

c++ - 在排序和旋转的数组中搜索

c - 我们如何在C中定义和使用函数内的结构?

javascript - 如何在 dmy 格式的日期之间循环

javascript - 按钮的点击事件