Javascript嵌套循环不显示完整矩阵

时间:2018-05-16 12:00:26

标签: javascript loops

我正在尝试打印一个坐标列表,我认为嵌套循环是适当的方法,所以我编写了以下代码(非常简单):

var x = 23;
var y = 34;
var z = 28;

var div = document.getElementById("coordinates");

div.innerHTML += "<ul>";

for (var i = 1; i <= x; i++) {
    for (var j = 1; j <= y; j++) {
        for (var k = 1; k <= z; k++) {
            div.innerHTML += "<li>X: " + i + " Y: " + j + " Z: " + k + "</li>";
        }
    }
}

div.innerHTML += "</ul>";

当我这样做时,我期待非常多的元素(在这种情况下是23 * 34 * 28元素),但我得到了这个:

X: 1 Y: 1 Z: 1
X: 1 Y: 1 Z: 2
X: 1 Y: 1 Z: 3
X: 1 Y: 1 Z: 4
X: 1 Y: 1 Z: 5
X: 1 Y: 1 Z: 6
X: 1 Y: 1 Z: 7
X: 1 Y: 1 Z: 8
X: 1 Y: 1 Z: 9
X: 1 Y: 1 Z: 10
X: 1 Y: 1 Z: 11
X: 1 Y: 1 Z: 12
X: 1 Y: 1 Z: 13
X: 1 Y: 1 Z: 14
X: 1 Y: 1 Z: 15
X: 1 Y: 1 Z: 16
X: 1 Y: 1 Z: 17
X: 1 Y: 1 Z: 18
X: 1 Y: 1 Z: 19
X: 1 Y: 1 Z: 20
X: 1 Y: 1 Z: 21
X: 1 Y: 1 Z: 22
X: 1 Y: 1 Z: 23
X: 1 Y: 1 Z: 24
X: 1 Y: 1 Z: 25
X: 1 Y: 1 Z: 26
X: 1 Y: 1 Z: 27
X: 1 Y: 1 Z: 28

当我预料到它会继续这样的事情时:

X: 1 Y: 2 Z: 1
X: 1 Y: 2 Z: 2
X: 1 Y: 2 Z: 3
X: 1 Y: 2 Z: 4
...

就像它只通过两个第一个循环一次循环。

我想我正在尝试做一些非常简单的事情,所以我做错了什么?

PD:现在我不需要保存内存或任何类型的优化,我知道如果x,y,z值很高,这样的循环可能会很大。

1 个答案:

答案 0 :(得分:8)

  

现在我不需要保存内存或任何类型的优化,我知道如果x,y,z值很高,这样的循环可能会很大。

你确实需要,因为你要求浏览器做一些巨大的数量的不必要的工作,并且可能达到了限制;否则代码就好了。

x.innerHTML += ...是一个反模式。每次从innerHTML读取时,浏览器都必须遍历您使用它的元素的完整树并构建一个字符串在内存中使用该DOM树的HTML表示;每次分配给它时,浏览器都必须拆除旧树,解析新的HTML,并构建新的DOM元素以替换旧树。 +=正在阅读,添加更多内容,然后进行分配。

当我写这篇文章时(已经编写了下面的代码片段),jsFiddle我将原始代码放入仍在运行并且在我开始这个答案之前一直在运行。 :-)(编辑:它终于停止了,并且显示了完整列表。)

而是创建新节点并附加它。在您的情况下,您甚至可以将所有li添加到ul,然后再将其添加到文档中,然后通过一次操作将其添加到文档中。如果我这样做,它可以很快地运作:

var x = 23;
var y = 34;
var z = 28;

var div = document.getElementById("coordinates");

var ul = document.createElement("ul");

for (var i = 1; i <= x; i++) {
    for (var j = 1; j <= y; j++) {
        for (var k = 1; k <= z; k++) {
          var li = document.createElement("li");
          li.appendChild(
            document.createTextNode(
              "X: " + i + " Y: " + j + " Z: " + k
            )
          );
          ul.appendChild(li);
        }
    }
}

div.appendChild(ul);
<div id="coordinates"></div>