输入元素与 'for' 循环具有相同的值

Input elements having the same value with 'for' loop

我刚刚试验了 JavaScript 并尝试了这段代码。

var elements = document.getElementsByTagName("p");
var n = elements.length; // Should be: 10

for (var i = 0; i < n; i++) {
  elements[i].onclick = function () {
    console.log("This is element #" + i);
  };
}
<p>Element: #1</p>
<p>Element: #2</p>
<p>Element: #3</p>
<p>Element: #4</p>
<p>Element: #5</p>

但是,当代码为 运行 时,会发生一些奇怪的事情。基本上,例如,如果您点击元素 #1,它会说您点击了元素 #5。


这是我很想知道的:

  1. 为什么会这样?
  2. 是否有解决办法?

将 var 更改为:

for (let i = 0; i < n; i++) {
  elements[i].onclick = function () {
    console.log("This is element #" + i);
  };
}

您可以使用下面的代码来更正问题。

var elements = document.getElementsByTagName("p");
var n = elements.length;

function makeHandler(num) {
     return function() {
         console.log("This is element #" + num);
     };
};

for (var i = 0; i < n; i++) {
    elements[i].onclick = makeHandler(i + 1);
}

让我们解释一下代码。


基本上,在这段代码中,每次我们通过循环时,makeHandler 都会立即执行,每次接收 i + 1 的 then-current 值并将其绑定到作用域 num变量。

外部函数 (makeHandler) returns 内部函数(匿名函数)(也使用此作用域 num 变量)和元素的 onclick 已设置到那个内部函数。

这确保每个 onclick 接收并使用正确的 i 值(通过作用域 num 变量)。