在JavaScript中循环访问数组
在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
在2015年的ECMAScript(以下简称“和谐”版本)推出的功能。
它是这样工作的:
// 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 (let 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
语法不应该用于循环数组。
您可以使用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
。
上一篇: Loop through an array in JavaScript
下一篇: Stash only one file out of multiple files that have changed with Git?