【问题标题】:Best practice: Javascript for loop最佳实践:Javascript for 循环
【发布时间】:2018-09-23 09:02:53
【问题描述】:

编写 JavaScript for 循环的最佳实践是什么?

我一开始是这样写的:

for(var i = 0; i < array.length; i++){
    //do stuff
}

但是后来发现每次pass计算长度并不理想,所以应该更像:

var len = array.length;
for(var i = 0; i < len; i++){
    //do stuff
}

但是如果你减少而不是增加循环会更快:

var lenArr = array.length - 1;
for(var len = lenArr; len > 0; len--){
    //do stuff
}

但是,如果您只想中断一组嵌套循环中的一个循环,则这种循环实际上并不奏效,因此您应该养成使用标签的习惯:

var lenArr = array.length - 1;
var lenArr2 = array2.length - 1;

loop1: for(var len = lenArr; len > 0; len--){
    loop2: for(var len2 = lenArr2; len2 > 0; len2--){
        //do stuff
        break loop2;
    }
}

是否还有其他需要更改的地方,或者这是在 JavaScript 中编写 for 循环的最佳做法?

【问题讨论】:

  • 最佳实践 IMO 是尽可能完全避免 for 循环 - 与数组方法不同,它们需要手动迭代,没有任何抽象,当新手开发人员使用 var 时会出现提升问题,以及不可组合。除了速度之外,Array 方法在各个方面都更好,而且速度很少需要担心,除非您正在编写库。但这是基于意见的。
  • 您可以使用jsperf.com 编写测试以相互运行这些不同的场景以检查它们的性能。有时结果会让您感到惊讶,浏览器制造商会优化某些路径,使其比其他路径更快。
  • break loop2; ... 看起来很糟糕的代码
  • 我做的很快,但无论如何,在 Chrome 中,[for 循环仍然胜过 forEach](jsperf.com/for-vs-foreach-anied/1)。也就是说,性能是其中的一部分——如果你的数据集很小并且性能不是关键因素,你可能会在规模上更重地衡量可读性......
  • 如果你想要速度......并且你正在处理大型数组......不要在 Chrome 或 Edge(forEach 等)中使用数组原生方法 - 它们的速度慢得令人麻木 - 93% 和分别慢 98%!! (与好的浏览器相比,差异更像是 3%)

标签: javascript loops for-loop


【解决方案1】:

如果你有数组而不是使用forEach

array.forEach(ele=> {

});

这样您就可以保持代码简洁易懂,而不必编写与长度相关的代码。

Break 不适用于 forEach,但您可以写 return 来表示从 forEach 中脱颖而出

array.forEach(ele=> {
   ele.array.forEach(ele=> {
     //do stuff 
     return;
   });
});

注意:

  1. for 循环更快。
  2. forEach 速度较慢,但​​更适合函数式编程范例。

答案基于问题的标题:最佳实践,为什么给出使用 forEach 的建议。

【讨论】:

  • 您可能想提一下,当使用forEach 时,您无法避免循环遍历整个数组...即没有等同于break ...当然,您可以使用@改为 987654328@ 或 .every
  • @JaromandaX - 似乎对问题的修改让我通过了我
  • 不是真的 - 他从一开始就有break 的东西:p - 他所做的只是用实际进入循环体的代码修复“这更快”代码:p
  • return 不会脱离forEach,它只是停止当前迭代——就像continue;for 循环中一样。
  • 是的,我在 foreach 中使用 return 来“继续”循环
【解决方案2】:

实际上,我更喜欢for...of,因为您仍然可以使用break,而且它的打字少得多,而且可读性更强:

  for(const el of array)

如果您也需要索引:

  for(const [index, el] of array.entries())

或者如果您需要从后向前迭代:

 for(const el of array.reverse())

【讨论】:

    【解决方案3】:

    关于保存 array.length 尽管在 JavaScript 的早期,将 .length 值保存在变量中有所不同,但现代 JavaScript 引擎只会运行 for 循环和第一个版本一样快。

    向后迭代也不能保证在现代引擎上运行得更快。还有一个考虑因素是 CPU 被优化以预测前向内存引用,尽管这仅在 JS 引擎决定将数组存储为连续内存块时才相关。

    至于标签的使用:大多数人不会考虑这种最佳做法。之前的优化(关于.length)涉及循环的所有次迭代,此问题仅适用于两个循环的单次退出。无论您使用什么解决方案,它都代表恒定时间,并且不能成为循环整体性能的决定因素。

    当然,在这种情况下,我会遵循良好的编码习惯而不是微小的优化考虑。当您只想退出当前循环时,单个break 就足够了。

    如果你想快速退出嵌套循环,那么考虑将它们放在一个函数中,这样你就可以使用return

    function performNestedLoop(array, array2) {
        for(var len = lenArr; len > 0; len--){
            for(var len2 = lenArr2; len2 > 0; len2--){
                //dostuff
                if (exitCondition) return;
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      您可以使用Array.forEach

      使用forEach的优势如下

      1. 提供功能范围,当您需要在循环中执行一些异步功能时,您将不需要创建任何IIFE
      2. 它可以让您的代码保持整洁并更加符合上下文

      示例代码

      arr.forEach(function(item, index){
          // do stuff    
      });
      

      【讨论】:

        猜你喜欢
        • 2012-09-20
        • 1970-01-01
        • 1970-01-01
        • 2011-02-23
        • 1970-01-01
        • 2013-04-10
        • 1970-01-01
        • 1970-01-01
        • 2014-11-25
        相关资源
        最近更新 更多