在 Java 中,您可以使用for
循环遍历数组中的对象,如下所示:
String[] myStringArray = {"Hello", "World"};
for (String s : myStringArray)
{
// Do something
}
你能用 JavaScript 做同样的事吗?
使用顺序for
循环:
var myStringArray = ["Hello","World"];
var arrayLength = myStringArray.length;
for (var i = 0; i < arrayLength; i++) {
alert(myStringArray[i]);
//Do something
}
@zipcodeman 建议使用for...in
语句,但是应该避免迭代数组for-in
,该语句用于枚举对象属性。
它不应该用于类似数组的对象,因为:
第二点是它可以给你很多问题,例如,如果你扩展Array.prototype
对象以包含一个方法,那么该属性也将被枚举。
例如:
Array.prototype.foo = "foo!";
var array = ['a', 'b', 'c'];
for (var i in array) {
alert(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...
alert("prop: " + prop + " value: " + obj[prop])
}
}
在上面的示例中, hasOwnProperty
方法允许您只枚举自己的属性 ,就是它,只有对象物理上具有的属性,没有继承属性。
我建议你阅读以下文章:
是的,但只有当你实现包括for
... of
中介绍的特征的 ECMAScript 2015 年 (以下简称 “和谐” 版本)。
它的工作原理如下:
// REQUIRES ECMASCRIPT 2015+
var s, myStringArray = ["Hello", "World"];
for (s of myStringArray) {
// ... do something with s ...
}
或者更好,因为 ECMAScript 2015 还通过let
和const
提供了块范围的变量:
// REQUIRES ECMASCRIPT 2015+
const myStringArray = ["Hello", "World"];
for (const s of myStringArray) {
// ... do something with s ...
}
// s is no longer defined here
然而,许多 JavaScript 开发人员仍然在一个尚未出现的环境中工作 - 特别是如果编写代码以在 Web 浏览器中运行,那么网站开发人员通常无法确定他们的客户将使用哪种浏览器 / 版本。
如果您可以假设 JavaScript 解释器符合以前版本的 ECMAScript 规范(例如,排除了 9 之前的 Internet Explorer 版本),那么您可以使用forEach
迭代器方法而不是循环。在这种情况下,您传递一个要在数组中的每个项目上调用的函数:
var myStringArray = [ "Hello", "World" ];
myStringArray.forEach( function(s) {
// ... do something with s ...
} );
但是,如果即使这样做太多了,而且你想要的东西适用于所有版本的 JavaScript,那么你必须使用一个显式的计数循环。最安全的版本,正确处理稀疏数组,如下所示:
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%。
您将经常在循环初始化子句中看到完成的长度缓存,如下所示:
var i, len, myStringArray = [ "Hello", "World" ];
for (len = myStringArray.length, i=0; i<len; ++i) {
其他人提到的for
... in
语法用于循环对象的属性; 因为 JavaScript 中的数组只是一个具有数字属性名称的对象(以及一个自动更新的length
属性),所以理论上可以用它循环一个数组。但问题是它并不局限于数值属性值(请记住,即使方法实际上只是其值为闭包的属性),也不会按数字顺序迭代它们。因此, for
... in
语法不应该用于循环遍历 Arrays。
您可以使用map
,这是一种函数式编程技术,也可以在Python和Haskell等其他语言中使用。
[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
。