首页 > JavaScript > 在 Java 中,您可以使用循环遍历数组中的对象,在JavaScript 中做同样的吗

在 Java 中,您可以使用循环遍历数组中的对象,在JavaScript 中做同样的吗

上一篇 下一篇

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

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

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

分割线

网友回答:

是的,假设您的实现包括…ECMAScript 2015 中引入的功能(“和谐”版本)…如今,这是一个非常安全的假设。forof

它的工作原理是这样的:

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

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

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

(变量在每次迭代中都是不同的,但只要它不在那里被修改,仍然可以在循环体中声明。sconst

关于稀疏数组的说明:JavaScript 中的数组实际上可能没有其报告的那么多项目;该数字只是比存储值的最高索引大 3。如果数组包含的元素少于其长度所指示的元素,则称其为稀疏。例如,拥有一个仅在索引 12、247 和 248 处包含项目的数组是完全合法的;这样的数组是 3,尽管它实际上只存储 <> 个值。如果您尝试访问任何其他索引处的项目,该数组似乎具有该值,但该数组仍然与实际存储了值的数组不同。您可以通过多种方式看到这种差异,例如在节点 REPL 显示数组的方式中:lengthlengthundefinedundefined

> a              // array with only one item, at index 12
[ <12 empty items>, 1 ]
> a[0]           // appears to have undefined at index 0
undefined
> a[0]=undefined // but if we put an actual undefined there
undefined
> a              // it now looks like this
[ undefined, <11 empty items>, 1 ]

因此,当您想要“遍历”数组时,您需要回答一个问题:是要遍历其长度指示的整个范围并处理任何缺失的元素,还是只想处理实际存在的元素?这两种方法都有很多应用;这只取决于您使用数组的目的。undefined

如果使用 .. 迭代数组,则循环的主体将执行时间,并且循环控制变量设置为数组中实际不存在的任何项。根据“执行某些操作”代码的详细信息,该行为可能是您想要的,但如果不是,则应使用其他方法。foroflengthundefined

当然,一些开发人员别无选择,只能使用不同的方法,因为无论出于何种原因,他们的目标是尚未支持的JavaScript版本……forof

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

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

当然,如果您的实现支持 ES6+,您可以使用箭头函数:

myStringArray.forEach( s => { 
     // ... do something with s ...
} );

与 … 不同,它只为数组中实际存在的元素调用函数。如果传递我们假设的数组,其中包含三个元素,长度为 248,它只会调用该函数三次,而不是 248 次。如果这是您想要处理稀疏数组的方式,即使您的解释器支持….forof.forEach.forEachforof

最后一个选项适用于所有版本的 JavaScript,是一个显式计数循环。您只需从 0 到比长度小 <> 计数,并将计数器用作索引。基本循环如下所示:

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

此方法的一个优点是可以选择如何处理稀疏数组。上面的代码将完整运行循环的主体,设置为任何缺少的元素,就像..;如果您只想处理稀疏数组中实际存在的元素,例如 ,则可以在索引上添加一个简单的测试:lengthsundefinedforof.forEachin

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

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

显式计数循环还意味着您可以根据需要访问每个值的索引。索引也作为额外的参数传递给您传递给的函数,因此您也可以通过这种方式访问它:forEach

myStringArray.forEach( (s,i) => {
   // ... do something with s and i ...
});

for…不会给你与每个对象关联的索引,但只要你迭代的对象实际上是 的实例(而不是其他可迭代类型之一.. 工作),你可以使用 Array#entries 方法将其更改为 [index, item] 对的数组,然后迭代它:ofArrayforof

for (const [i, s] of myStringArray.entries()) {
  // ... do something with s and i ...
}

这。。。其他人提到的语法用于循环对象的属性;由于 JavaScript 中的数组只是一个具有数字属性名称(以及自动更新的属性)的对象,因此理论上您可以使用它遍历 Array。但问题是它不将自身限制为数值属性值(请记住,即使是方法实际上也只是其值为闭包的属性),也不能保证按数字顺序迭代这些值。因此,…语法不应用于遍历数组。forinlengthforin

分割线

网友回答:

三个主要选项:

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

详细示例如下。


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规范发布(2009年<>月)时已近十年,它已被桌面,服务器和移动环境中的几乎所有现代引擎实现,因此使用它们是安全的。

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

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

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

优点

  • 非常简短和简洁。
  • 声明

缺点

  • 不能使用break / continue

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

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 . I’ve seen this anti-pattern so many times.map

Anti-pattern:

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

优点

  • 它可以迭代各种各样的对象。
  • 可以使用正常的流量控制语句 ( / )。breakcontinue
  • 可用于循环访问串行异步值。

缺点

  • 如果您的目标是较旧的浏览器,则转译后的输出可能会让您大吃一惊。

请勿使用for...in

@zipcodeman建议使用该语句,但对于迭代数组,应避免使用该语句,该语句旨在枚举对象属性。for...infor-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

我建议您阅读以下文章:

  • 枚举与迭代

分割线

网友回答:

您可以使用 ,这是一种函数式编程技术,也可以在其他语言(如 Python 和 Haskell)中使用。map

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

一般语法为:

array.map(func)

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

的返回值是另一个数组,因此您可以像这样使用它: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

模板简介:该模板名称为【在 Java 中,您可以使用循环遍历数组中的对象,在JavaScript 中做同样的吗】,大小是暂无信息,文档格式为.编程语言,推荐使用Sublime/Dreamweaver/HBuilder打开,作品中的图片,文字等数据均可修改,图片请在作品中选中图片替换即可,文字修改直接点击文字修改即可,您也可以新增或修改作品中的内容,该模板来自用户分享,如有侵权行为请联系网站客服处理。欢迎来懒人模板【JavaScript】栏目查找您需要的精美模板。

相关搜索
  • 下载密码 lanrenmb
  • 下载次数 268次
  • 使用软件 Sublime/Dreamweaver/HBuilder
  • 文件格式 编程语言
  • 文件大小 暂无信息
  • 上传时间 02-16
  • 作者 网友投稿
  • 肖像权 人物画像及字体仅供参考
栏目分类 更多 >
热门推荐 更多 >
自适应 响应式 微信素材 微信模板 html5 微信公众平台 微信文章 企业网站 微信图片 单页式简历模板
您可能会喜欢的其他模板