let p = document.createElement("p");
let a = document.createElement("a");
for(let i=1; i <= 5; i++) {
p.textContent = i;
a.appendChild(p);
console.log(a);
}
结果
<a><p>5</p></a>
<a><p>5</p></a>
<a><p>5</p></a>
<a><p>5</p></a>
<a><p>5</p></a>
我正在努力理解这个基本概念。我知道当我在for循环中移动let p = document.createElement("p");
的赋值时,我会得到所需的结果
<a><p>1</p></a>
<a><p>2</p></a>
<a><p>3</p></a>
<a><p>4</p></a>
<a><p>5</p></a>
我肯定认为textContent
属性的值会被i
覆盖,但是从第一次传递开始,i
会立即跳转到5。
我只是想了解这背后的逻辑。谢谢,非常感谢任何帮助。
答案 0 :(得分:4)
如果将p
的声明留在循环之外,那么元素对象只创建一次,而如果将它放在循环中,则每次迭代都会创建一个新对象。
您在第一种情况下看到的原因是p
是一个对象,您将一次又一次地附加到a
。由于它是同一个对象,因此修改它会随处改变它。
在第二种情况下,您有多个不同的元素对象,您要附加到a
。修改一个对其他人没有影响。
编辑:这是因为console.log
实际上在循环完成后记录,如Patrick Evans在评论中所述。
另外,您是否注意到a
总是有一个元素,即使我们多次调用appendChild
?
如果你想拥有多个不同的p
元素,但是一个p
个对象会增加,那么这段代码应该可以工作:
let p = document.createElement("p");
let a = document.createElement("a");
for(let i=1; i <= 5; i++) {
p.textContent = i;
a.appendChild(p.cloneNode(true));
console.log(a);
}
答案 1 :(得分:2)
这是因为变量p
是指向您创建的dom对象的指针。 这不是数据本身!它通过 参考 传递数据。
基本上,当你追加它时,你要附加对象的引用而不是多次复制(克隆)对象。
这就是为什么当您更改对象的值时,引用它的所有位置都会受到影响。
就像你说的那样,为了解决这个问题,只需将let p = document.createElement("p");
放入for循环中,或者另外使用p.cloneNode(true)
,这样就会复制(克隆)你的对象。
答案 2 :(得分:0)
如果我们逐步完成您的代码,最好理解这一点:
let p = document.createElement("p"); // create an element
// loop through this 5 times
for(let i=1; i <= 5; i++) {
p.textContent = i;
a.appendChild(p);
console.log(a);
}
在第一次迭代i = 1
我们将p.textContent
设置为1
在第二次迭代i = 2
,我们将p.textContent
设置为2
。
但是等等......第一次迭代(p
)中使用的i = 1
与第二次迭代中的i = 2
有何不同(p
)?它们没有区别,指的是相同的p.textContent
变量。在第二步中,您将覆盖在第一次迭代中设置的p
。
相反,您应该在循环内创建一个新的p
变量,而不是在循环外部。这可确保每个// loop through this 5 times
for(let i=1; i <= 5; i++) {
let p = document.createElement("p"); // create an element
p.textContent = i;
a.appendChild(p);
console.log(a);
}
变量都是唯一的。
请尝试以下方法:
node_modules
答案 3 :(得分:-1)
据我所知,console.log
是同步和异步之间的一种灰色区域。显然,您显示的所有控制台日志都显示整个for循环完成后的状态,即使它们被称为中循环。
我们通常可以将console.log
视为同步,因为它不会返回任何内容。但它实际上调用的浏览器功能超出了javascript的范围。我想如果你记录的是&#34;简单&#34;足够(字符串,浅层对象等),然后可以立即评估日志显示的内容。
但是如果您正在记录的内容非常复杂(如DOM元素),那么浏览器可能只保存对该对象的引用,然后在浏览器到达时向我们显示日志时对该对象进行解析。在这种情况下,这将在整个for循环完成之后。