在 JavaScript 中循环遍历数组 [英] Loop through an array in JavaScript

查看:26
本文介绍了在 JavaScript 中循环遍历数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

String[] myStringArray = {"Hello", "World"};for (String s : myStringArray){//做点什么}

你能用 JavaScript 做同样的事情吗?

解决方案

三个主要选项:

  1. for (var i = 0; i
  2. xs.forEach((x, i) => console.log(x));
  3. for (const x of xs) { console.log(x);}

详细示例如下.


1.顺序 for 循环:

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

优点

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

缺点

  • 过于冗长
  • 当务之急
  • 容易出现一对一错误(有时也称为围栏错误)

2.Array.prototype.forEach:

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

const array = ["one", "two", "three"]array.forEach(函数(项目,索引){控制台日志(项目,索引);});

自 ES5 规范发布之时(2009 年 12 月)已经快十年了,几乎所有现代引擎都在桌面、服务器和移动环境中实现了它,因此使用它们是安全的.

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

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

箭头功能也被广泛实现,除非您计划支持古老的平台(例如,Internet Explorer 11);你也安全了.

优点

  • 非常简短.
  • 声明式

缺点

  • 不能使用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 化为一个值,例如,您想对一个数字数组求和,则应该使用reduce 方法.

反模式:

const numbers = [1,2,3,4,5];常量总和 = 0;numbers.forEach(num => { sum += 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 语句.

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

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

let colors = ['red', 'green', 'blue'];for (const color of colour){控制台日志(颜色);}

优点

  • 它可以迭代各种各样的对象.
  • 可以使用普通的流程控制语句(break/continue).
  • 用于迭代串行异步值.

缺点

不要使用for...in

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

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

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

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

例如:

Array.prototype.foo = "foo!";var 数组 = ['a', 'b', 'c'];for (var i in array) {控制台日志(数组[i]);}

以上代码将控制台记录a"、b"、c"和foo!".

如果您使用一些严重依赖原生原型增强的库(例如 MooTools).

for-in 语句,正如我之前所说的,用于枚举对象属性,例如:

var obj = {一":1,乙":2,c":3};for (var prop in obj) {如果 (obj.hasOwnProperty(prop)) {//或者 if (Object.prototype.hasOwnProperty.call(obj,prop)) 为了安全...console.log("prop: " + prop + " value: " + obj[prop])}}

在上面的示例中,hasOwnProperty 方法允许您仅枚举自己的属性.就是这样,只有对象物理上拥有的属性,没有继承的属性.

我建议您阅读以下文章:

In Java you can use a for loop to traverse objects in an array as follows:

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

Can you do the same in JavaScript?

解决方案

Three main options:

  1. for (var i = 0; i < xs.length; i++) { console.log(xs[i]); }
  2. xs.forEach((x, i) => console.log(x));
  3. for (const x of xs) { console.log(x); }

Detailed examples are below.


1. Sequential for loop:

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

Pros

  • Works on every environment
  • You can use break and continue flow control statements

Cons

  • Too verbose
  • Imperative
  • Easy to have off-by-one errors (sometimes also called a fence post error)

2. Array.prototype.forEach:

The ES5 specification introduced a lot of beneficial array methods. One of them, the Array.prototype.forEach, gave us a concise way to iterate over an array:

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

Being almost ten years as the time of writing that the ES5 specification was released (Dec. 2009), it has been implemented by nearly all modern engines in the desktop, server, and mobile environments, so it's safe to use them.

And with the ES6 arrow function syntax, it's even more succinct:

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

Arrow functions are also widely implemented unless you plan to support ancient platforms (e.g., Internet Explorer 11); you are also safe to go.

Pros

  • Very short and succinct.
  • Declarative

Cons

  • Cannot use break / continue

Normally, you can replace the need to break out of imperative loops by filtering the array elements before iterating them, for example:

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

Keep in mind if you are iterating an array to build another array from it, you should use map. I've seen this anti-pattern so many times.

Anti-pattern:

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

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

Proper use case of map:

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

console.log(doubled);

Also, if you are trying to reduce the array to a value, for example, you want to sum an array of numbers, you should use the reduce method.

Anti-pattern:

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

Proper use of reduce:

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

console.log(sum);

3. ES6 for-of statement:

The ES6 standard introduces the concept of iterable objects and defines a new construct for traversing data, the for...of statement.

This statement works for any kind of iterable object and also for generators (any object that has a \[Symbol.iterator\] property).

Array objects are by definition built-in iterables in ES6, so you can use this statement on them:

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

Pros

  • It can iterate over a large variety of objects.
  • Can use normal flow control statements (break / continue).
  • Useful to iterate serially asynchronous values.

Cons

Do not use for...in

@zipcodeman suggests the use of the for...in statement, but for iterating arrays for-in should be avoided, that statement is meant to enumerate object properties.

It shouldn't be used for array-like objects because:

  • The order of iteration is not guaranteed; the array indexes may not be visited in numeric order.
  • Inherited properties are also enumerated.

The second point is that it can give you a lot of problems, for example, if you extend the Array.prototype object to include a method there, that property will also be enumerated.

For example:

Array.prototype.foo = "foo!";
var array = ['a', 'b', 'c'];

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

The above code will console log "a", "b", "c", and "foo!".

That can be particularly a problem if you use some library that relies heavily on native prototypes augmentation (such as MooTools).

The for-in statement, as I said before, is there to enumerate object properties, for example:

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

In the above example, the hasOwnProperty method allows you to enumerate only own properties. That's it, only the properties that the object physically has, no inherited properties.

I would recommend you to read the following article:

这篇关于在 JavaScript 中循环遍历数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆