为什么这个脚本不会陷入无限循环?

8
我试图理解从互联网上找到的一段代码。我不明白为什么在 while 循环中它不是一个无限循环。如果我将其中的 calculator.appendChild 更改为例如 console.log,它会一直运行下去。
 window.location.hash = 1;
 var calculator = document.createElement("div");
 calculator.id = "height-calculator";
 while (document.body.firstChild) {
    calculator.appendChild(document.body.firstChild);
 }
 document.body.appendChild(calculator);
 document.title = calculator.clientHeight;

基本上,在非空站点中总是有一个第一个子元素,因此条件始终为真。有人能解释一下为什么这样不会无限运行吗?


1
“calculator”元素在DOM之外,而while循环只是将所有“body”的子元素移动到“calculator”,因此在某个时候,“body”将为空,循环结束。关键在于,在循环期间,“calculator”本身不是“body”的子元素。 - user5734311
2个回答

11

一个元素只能是另一个元素的子元素之一。

calculator.appendChild(document.body.firstChild);

当你将document.body.firstChild连接到你的计算器时,它会自动“分离”自身,并使 body 最终失去所有子元素。


但是难道不会有另一个firstChild吗?它不同于之前的,但是接下来的那个将成为现在的第一个子节点,对吧? - Abhay Maurya
但会不会有另一个firstChild呢?它不是之前那个,而是接下来的那个将变成firstChild...是吗?是的,然后循环再次运行并取出这个子元素,直到没有更多的子元素。 - tkausl
所以基本上appendChild将元素从body中移除,并添加到计算器中?我以为它会克隆它。 - B. Ma
不,它会“偷”走原始节点。如果你使用 cloneNode 克隆节点,它将永远循环(或者说直到内存耗尽)。 - tkausl

1
所以这个过程分为三个简单的步骤:
  1. var calculator = document.createElement("div"); 这一行代码在DOM中外部创建了一个 div

  2. 然后循环将所有 body 的子元素移动到 calculator 中,直到结束,除非 body 有无限的子元素,这是不可能的。

  3. document.body.appendChild(calculator);calculator 移动到 body 下面

所以基本上有两个主要实体 bodycalculator,脚本将所有 body 的子元素移动到 calculator,然后将 calculator 移动到 body

换句话说,脚本将 body 的所有子元素转换为 bodygrandchildren,而 body 的唯一子元素变成了 calculator

我知道我写了太多,但是在一段时间后,通过阅读其他评论和答案,我自己理解了它,所以我只是想把它留在这里,为了将来的自己和需要更多解释的任何人 LOL


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接