【问题标题】:Is there a limit to how many levels you can nest in JavaScript?在 JavaScript 中可以嵌套多少层有限制吗?
【发布时间】:2016-05-15 02:08:51
【问题描述】:

假设您有一个非常复杂的算法,需要数十个 for 循环。

JavaScript 对嵌套循环的深度有限制还是没有限制?

深层嵌套 for 循环的最佳做法是什么?

我尝试在 MDN 上搜索,但找不到我要查找的内容

编辑

我正在查看是否有内置限制。例如,如果你有这样的事情

If ( a = 1, a < 3, a++) {
    if (b = 1; b < 3; b++) {
        ...
        if (cd = 1; cd < 3; cd++) 

这真的可能吗,或者 JS 会抛出错误

编辑:这是一个理论上的示例,说明您何时可能需要此

您想查找数组中的任何 500 个数字之和是否等于另一个数字。您需要大约 500 个循环才能将数字添加到组合数组中,然后过滤它们以找到它们相对于第三个数字的总和。

宇宙中是否有足够的空间来存储这么多数据?

【问题讨论】:

  • 您需要更具体地了解该功能。
  • 你可以试试递归函数
  • 您会遇到堆栈溢出问题。规范没有限制,浏览器有。但是还有像tail-call optimizationtrampolining 这样的技术,这些技术可以帮助减少堆栈大小等。这意味着如果你真的想要,你可以拥有更高级别的递归。编辑:这很好解释stackoverflow.com/questions/25228871/…
  • “宇宙中会有足够的空间来存储这么多数据吗?”是的。数组中有500个数字?然后计算出所有的排列?即 500^2=250k。 是的,宇宙中至少有 250k 的空间

标签: javascript for-loop nested-loops limits cyclomatic-complexity


【解决方案1】:

规范没有限制。由于内存/堆栈溢出,可能在任何实现中都会受到限制...

例如,这很好用:

var s = 0;
var is = new Array(11);

for(is[0] = 0; is[0] < 2; is[0]++) {
  for(is[1] = 0; is[1] < 2; is[1]++) {
    for(is[2] = 0; is[2] < 2; is[2]++) {
      for(is[3] = 0; is[3] < 2; is[3]++) {
        for(is[4] = 0; is[4] < 2; is[4]++) {
          for(is[5] = 0; is[5] < 2; is[5]++) {
            for(is[6] = 0; is[6] < 2; is[6]++) {
              for(is[7] = 0; is[7] < 2; is[7]++) {
                for(is[8] = 0; is[8] < 2; is[8]++) {
                  for(is[9] = 0; is[9] < 2; is[9]++) {
                    for(is[10] = 0; is[10] < 2; is[10]++) {
                      s++;
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

document.write(s);

【讨论】:

    【解决方案2】:

    在编写人类应该阅读和维护的代码时,您无需担心最大的嵌套级别。您可以毫无问题地嵌套数百个循环。

    但是,您应该尽可能避免它!在某些时候,有人必须理解你的代码(很可能是你,当你在调试时!)并且会诅咒你。应该可以将内部循环提取到具有有意义名称的单独函数中。

    【讨论】:

      【解决方案3】:

      只是为了启动一个简短的测试,我已经修改为不计算循环次数,因为看到内存限制......这段代码(请不要使用它,你的机器会讨厌你):

          function x () {
          function newLoop (index) {
              var y = [];
              console.log("index");
              for (i = index; i < index+1000; i++) {
                  y.push(i);
                  if(i == index+999) {
                      console.log(i);
                      newLoop(i);
                  }
              }
          }
          newLoop(0);
      }
      x();
      

      已停止将 499500 记录到控制台。这可能会碰到一些安全开关或内存限制。

      这是 500 个嵌套循环。

      在使用此代码的较轻版本的早期测试中,我在第一秒内就获得了多达 999 个嵌套循环,代码又阻塞了我的浏览器几秒钟(但由于“太每秒向控制台发送许多消息”错误)。

      在那之后我不太关心更多细节,也没有看到更详细描述的好处,但是(在我的项目中)我正在遍历 HTML,其中包含大量布局错误的嵌套循环页面和这些结果超出了我的需求。

      TL;DR:内存比循环的数量更重要,但我已经超过了 1000 个嵌套循环。不过请不要使用那么多:)

      PS。这是在 Edge 中运行的,版本检查我的帖子的日期:)

      【讨论】:

      • 在我相当现代的笔记本电脑(华为 matebook 2020)上,它停止在 140k 左右。 Visual Studio编译的c++嵌套层数在100左右,这似乎是合理的。
      猜你喜欢
      • 2017-09-28
      • 1970-01-01
      • 1970-01-01
      • 2016-08-31
      • 2016-04-01
      • 1970-01-01
      • 2016-10-15
      • 2012-02-05
      • 1970-01-01
      相关资源
      最近更新 更多