【问题标题】:Why does this particular Javascript loop only work when reassigning a variable?为什么这个特定的 Javascript 循环仅在重新分配变量时才起作用?
【发布时间】:2016-10-13 21:36:45
【问题描述】:

所以我的目标是在 Javascript 中创建一个在页面上随机放置一些 div 的函数。最终,我想用图片填充这些 div,这样它就产生了图片被随机扔在桌子上的想法。我想出了一个 for 循环,现在它可以工作了,但我不明白为什么它以前不能工作。

var wrapper = document.getElementById("wrapper");
var xvalue;
var yvalue;

for (var i = 0; i < 3; i++) {
  var newDiv = document.createElement("div");
  xvalue = Math.floor(Math.random() * 400);
  yvalue = Math.floor(Math.random() * 400);
  newDiv.setAttribute("class", "frame");
  newDiv.style.top = yvalue+"px";
  newDiv.style.left = xvalue+"px";
  wrapper.appendChild(newDiv);
}

之前,我已经移动了这条线:

var newDiv = document.createElement("div");

在实际的 for 循环之前。由于它只用于创建一个新的 div,我想我不妨在循环之外声明变量。然而,这样做会导致它在同一个位置重复生成相同的div 次。通常我理解为什么将一个固定变量放在 for 循环之外会产生相同的结果,但在这里我不明白为什么。

提前致谢!

大安

【问题讨论】:

  • 你不明白为什么只创建一个div就只创建一个div?
  • 但它是一个for循环不是吗?当我告诉它创建一个新的 div [i] 次时,它不应该生成这么多次吗?此外,这并没有回答我的问题,这就是为什么将 createElement 放在循环中会如此彻底地改变结果
  • 因为您为所有迭代创建了一个 div。因此,当它在循环之外时,您每次都在操作相同的 div。
  • 如果将创建元素的代码放在循环之外,那么循环显然不会影响创建多少元素。
  • 这是一个关于范围和 javascript 编译阶段的精彩视频。 youtube.com/watch?v=nRZri_CHqnA

标签: javascript for-loop


【解决方案1】:

如果你放

var newDiv = document.createElement("div");

在循环之外,您将只有一个对象并在三个周期内对其进行操作。你不会有三个对象...

顺便说一句,将代码中的所有var 移到顶部而不进行赋值(参见下面的代码)。

变量声明被提升到顶部!

More about hoisting here.

您的代码在行为上看起来不同。通过将所有 var 放在顶部,它看起来就像它实际工作的方式一样,而且效果要好得多(便于理解和调试)。

您更正的代码是:

var i, newDiv, xvalue, yvalue, wrapper;

wrapper = document.getElementById("wrapper");

for (i = 0; i < 3; i++) {
  newDiv = document.createElement("div");
  xvalue = Math.floor(Math.random() * 400);
  yvalue = Math.floor(Math.random() * 400);
  newDiv.setAttribute("class", "frame");
  newDiv.style.top = yvalue + "px";
  newDiv.style.left = xvalue + "px";
  wrapper.appendChild(newDiv);
}

【讨论】:

  • 我不确定我是否同意var 的评论。通过不使用 var,您将在全局范围内声明一个变量,这可能会导致各种麻烦。如果您需要将某些内容放在全局范围内,您应该明确说明并使用window.newDiv = ...。但是,可能有更好的方法来实现您的目标,而无需诉诸全球。此外,在这个特定示例中,OP 希望将 newDiv 限定为 for 循环。在我看来,newDiv var 将作为对最后创建的 div 的任意引用在我看来也很奇怪。
  • 不不不。我修改了我的答案,因为这不是我的意思。您应该使用 var(或 ES6+ 中的 let),但不要在代码中间,因为有提升。我并不是要完全省略它。请查看我的代码清理,其中所有vars 都在第一行。
  • 通过重新阅读您的评论,我感觉存在误解。您不能将var 限定为for () 循环,因为JS 没有块作用域,它只有函数作用域。按照上面的吊装链接了解更多关于这是什么的信息。如果您不喜欢孤立的 newDiv 引用,只需使用 newDiv = undefined;delete newDiv; 清理它。
  • 抱歉,是的,更新后的答案更有意义。而且我忘记了 ES5 中缺少块作用域。
  • @gargantuan 是的,正如你所指出的,即使是 ES6 也 sadly(或 幸运地?)没有块作用域...var .这就是为什么我们有let ;)
猜你喜欢
  • 2016-12-10
  • 1970-01-01
  • 1970-01-01
  • 2013-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-21
  • 2013-12-13
相关资源
最近更新 更多