事件监听器回调函数内的变量范围

时间:2018-03-08 17:09:40

标签: javascript

我曾经认为用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>

2 个答案:

答案 0 :(得分:0)

您的问题是关闭或词汇范围。由于词汇作用域,您将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

答案 1 :(得分:0)

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

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