在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方法允许你只枚举自己的属性,就是它,只有对象物理上具有的属性,没有继承的属性。

    我建议你阅读下面的文章:

  • 枚举VS迭代

  • 是的,但只有当你实现包括for ... of在2015年的ECMAScript(以下简称“和谐”版本)推出的功能。

    它是这样工作的:

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

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

    // 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

    链接地址: http://www.djcxy.com/p/611.html

    上一篇: Loop through an array in JavaScript

    下一篇: Stash only one file out of multiple files that have changed with Git?