【问题标题】:scope of variable inside an event listener callback function事件侦听器回调函数内的变量范围
【发布时间】:2018-08-17 03:18:56
【问题描述】:

我曾经认为用 var 声明的变量的范围涵盖了 {} 之间的整个范围,但我尝试了以下示例,我想解释一下为什么我在回调函数中使用 'i' onclick 事件监听器的值不是 for 循环的索引,而是 for 循环完成后 i 的值。谢谢。

<html>
<head>
</head>
<body>
</body>
<script>
var components = ["1obj", "2obj", "3obj", "4obj", "5obj"];
createDivs(components);

function createDivs(components) {
    for (var i = 0; i < components.length; i++) {
        var image = document.createElement('div');
        image.innerHTML = components[i];
        image.index = i;
        image.onclick = function () {
            console.log(this.index); //gives the real index
            console.log(i); //gives the length of components+1
        };
        document.body.appendChild(image);
    }
}
</script>
</html>

【问题讨论】:

  • 使用 let 获得预期结果,查看此链接 - stackoverflow.com/questions/32313961/…
  • this 在 onclick 函数内部发生变化。这是一个新的范围。
  • 由于词法作用域,i 也是最后一个索引的值。当 onclick 发生时,我将永远是最后一个索引。您可以将 i 注入闭包中。看我的回答。
  • @Ali Chamas,你看我的回答了吗?
  • @jdmdevdotnet 是的,我确实感谢您的回答,我将其标记为正确的。伟大的解释完美地工作。关于这一点,我已经将索引值存储在 .index 中,因此它可以使用 this.index 工作,但您的解决方案更好,因为它是正确的方法,无需添加以后可能会造成混淆的新属性。

标签: javascript


【解决方案1】:

您的问题是闭包或词法作用域。由于词法作用域,您看到 i 作为最后一个索引的值。当 onclick 发生时,i 将始终是最后一个索引。您可以在闭包中注入i,如下所示:

  (function(_i) {
    image.onclick = function () {
        console.log(this.index); //gives the real index
        console.log(_i); //gives the length of components+1
    };
  })(i);

更多信息请参见here

【讨论】:

    【解决方案2】:

    所有函数都引用相同的范围。它不会像您想象的那样捕获当前值并存储当前值的单独副本。

    解决方案是使用一个函数来设置每个变量,使它们每个都有一个单独的词法环境。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-15
      • 1970-01-01
      • 2017-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多