【问题标题】:Does Javascript have an enhanced for loop syntax similar to Java'sJavascript 是否具有类似于 Java 的增强 for 循环语法
【发布时间】:2012-01-30 16:22:12
【问题描述】:

我想知道 JavaScript 是否具有增强的 for 循环语法,允许您遍历数组。例如,在 Java 中,您可以简单地执行以下操作:

String[] array = "hello there my friend".split(" ");

for (String s : array){
    System.out.println(s);
}

输出是:

hello
there
my
friend

有没有办法在 JavaScript 中做到这一点?还是我必须使用array.length 并使用标准的循环语法如下?

var array = "hello there my friend".split(" ");

for (i=0;i<array.length;i++){
    document.write(array[i]);
}

【问题讨论】:

    标签: javascript for-loop iterator


    【解决方案1】:

    JavaScript 有一个 foreach 样式的循环 (for (x in a)),但在 Array 上使用它是非常糟糕的编码习惯。基本上,array.length 方法是正确的。在您可以使用的较新 JavaScript 中还有一个 a.forEach(fn) 方法,但不能保证在所有浏览器中都存在 - 而且它比 array.length 方式慢。

    EDIT 2017:“我们会看看结果如何”,确实如此。现在在大多数引擎中,.forEach() 现在与for(;;) 一样快或更快,只要函数是内联的,即arr.forEach(function() { ... }) 很快,foo = function() { ... }; arr.forEach(foo) 可能不会。有人可能认为两者应该是相同的,但第一个比第二个更容易编译器优化。

    迟来的 EDIT 2020:现在有 for (const item of iterable),它解决了使用 for (item in iterable) 的缺点。

    【讨论】:

    • 那些相同的较新的 javascripts 实际上将数组索引视为一流的属性,从而减少了不好的做法。 (如果您当然支持较旧的 js 引擎,或者如果您的 Array 继承了属性并且您不检查它,这仍然很危险。下面 Rocket 的回答证明了这一点。)
    • @Rocket 的回答不会保护您免受对象本身设置的属性的影响。 a = [1,2,3]; a.listIndices = function() { for (i in a) { if (a.hasOwnProperty(i)) { console.log(i); } } }; a.listIndices() 将列出 0; 1; 2; listIndices
    • @Amadan:未设置的元素也不会在forEach 中迭代。
    • @Rocket:你是对的。值得庆幸的是,它跳过任何非数字索引,例如上面的listProperty
    • @ziesemer:没那么简单。如果我要追求性能,我绝对宁愿使用array.length 方法(带有缓存值)。 jsperf.com/for-vs-foreach/9
    【解决方案2】:

    使用适用于大多数现代浏览器的最新版本的 JavaScript,您可以这样做:

    array.forEach(function(x){
      document.write(x);
    });
    

    详情请见https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/forEach。如果您担心浏览器可能不支持此功能,您可以自己添加它,使用他们在“兼容性”下列出的(希望是缩小版的)实现版本。

    这有点过时了,但这是我几年前从 Mozilla 的页面导出的 forEach 的缩小兼容版本:

    if(!Array.prototype.forEach){Array.prototype.forEach=function(b){if(typeof b!="function"){throw new TypeError()}var a=this.length,d=arguments[1],c;for(c=0;c<a;c++){if(c in this){b.call(d,this[c],c,this)}}}};
    

    我从来没有遇到过任何问题,但是 Mozilla 页面上的实现已经通过一些额外的检查和代码进行了扩展,以使其与 ECMA-262 第 5 版 15.4.4.18 兼容。

    我有一个名为 common.js 的文件,我使用并包含在我的所有页面中以包含此文件,以及 JavaScript 1.6 引入的所有其他“数组附加”,如 https://developer.mozilla.org/en/JavaScript/New_in_JavaScript/1.6#Array_extras 中所列。 (我一直打算更新并发布此内容以供公众使用。)

    这可能不是最快的方法(有关某些细节,请参阅 http://jsperf.com/for-vs-foreach/15 - 感谢 Amadan 提供的链接) - 但对于简洁性和可维护性等,有一些话要说。此外,它会非常有趣看看在接下来的几个月和几年里,进一步的 JavaScript 引擎改进优化了多少这种差异。 :-)

    【讨论】:

      【解决方案3】:

      在 ES2015(ES6) 中,您可以使用 for-of 循环。除 IE 外,大多数浏览器都支持。

      let array = [10, 20, 30];
      
      for (let value of array) {
        console.log(value);
      }
      

      See the Mozilla explanation here

      【讨论】:

      • 简洁而完整的答案。
      【解决方案4】:

      for(s in array) 可以,但要小心,它和foreach 不一样。

      在这种情况下,s 是键(索引),而不是值。您还需要使用hasOwnProperty,因为in 也会循环通过对象的prototype

      for(s in array){
          if(array.hasOwnProperty(s)){
              console.log(array[s]);
          }
      }
      

      编辑:正如@Amadan 指出的那样,hasOwnProperty 确实 在像这样添加属性时会迭代它们:array.test = function(){}。我建议不要使用for...in

      EDIT2:如果您使用现代网络浏览器(任何不是 IE Array.forEach)。 @ziesemer 指出 Mozilla has a shim 如果你需要支持 IE

      array.forEach(function(s){
          console.log(s);
      });
      

      注意:我个人在我的 JavaScript 项目中使用 jQuery,而我使用 $.each

      $.each(array, function(i,s){
          console.log(s);
      });
      

      【讨论】:

      • 为什么不直接使用forEach? (请参阅 Amadan 或我的回答。)如果将事物直接分配给不打算被索引的数组 - 即使不是通过原型,即使这种方法也会中断。
      • 并非所有浏览器(我认为除了 IE 之外的所有浏览器)都支持 Array.prototype.forEach
      • forEach 从 IE 9 开始支持。对于旧版本,我的答案链接到的兼容性功能可用于添加对它的支持。
      • @Rocket 你在这里不会有异议,但我还是要支持垃圾。
      • @kojiro 数组索引至少从 ES3 开始就是一流的属性。我不知道那是不是新的,因为那是我真正研究过的最早的版本。所以所有浏览器都支持数组上的for...in循环,但这仍然不是一个好主意。
      【解决方案5】:

      在较新的 JavaScript 引擎中,Array 原型上有“forEach”方法。一些库使用类似的方法扩展原型本身。

      【讨论】:

      • 例如:jQuery 有$.each
      • @Rocket 是的,Prototype 将“.each”添加到 Array 原型中(或者它曾经,无论如何),像 Underscore 和 Functional 之类的东西也做类似的事情。
      【解决方案6】:
      x = [1,2,3];
      for (i in x) {
        console.log(i);
      }
      

      【讨论】:

      • 这不会按预期工作。在for...in 循环中,i 是键(索引),而不是值。你需要console.log(x[i])。您还应该检查if(x.hasOwnProperty(x)) 以确保您没有迭代prototype 中的属性。
      【解决方案7】:

      试试这个:

       var errorList = new Array();
       errorList.push("e1");
       errorList.push("e2");
            
       for (var indx in errorList) {
           alert(errorList[indx]);
       }
      

      【讨论】:

        猜你喜欢
        • 2012-07-25
        • 1970-01-01
        • 1970-01-01
        • 2011-01-20
        • 1970-01-01
        • 1970-01-01
        • 2013-06-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多