变量用作函数参数后发生变化

Variable changes after being used as function parameter

本文关键字:变化 参数 函数 变量      更新时间:2023-09-26

我正在循环浏览一些元素,然后添加新的元素,这些元素应该在单击时操作这些元素。这很难解释,所以请看一下这个Fiddle,让它更清楚:

http://jsfiddle.net/pgFcn/3/

有趣的部分是这个代码(为了简洁起见,是伪代码):

for (var i = 0; i < divs.length; i++) {
    var div = divs[i];
    someOtherElement.addEventListener("click", function () {
        testDiv(div); // always refers to the last div because variable is overwritten next loop
    });
}

我希望testDiv调用分别引用div 1、div 2和div 3,但它们都引用了div 3,因为变量在下一次循环迭代中会被覆盖。我该如何解决这个问题?

这是一个经典问题。以下是通常的解决方法:

for (var i = 0; i < divs.length; i++) {
    (function(div){
      someOtherElement.addEventListener("click", function () {
        testDiv(div);
      });
    })(divs[i]);
}

为了理解问题和解决方案,您必须知道,在JavaScript中,非全局变量的作用域是对声明它的函数的调用。这意味着

  • 在代码中,只有一个div变量
  • 在解决方案中,调用中间函数会生成不同的div变量

这是解决问题的另一种方法。。。

function testDiv(d) {
    // this doesn't work as expected, it always shows "Div 3"
    alert(d.innerText);
}
var divs = document.getElementsByTagName("div");
for (var i = 0; i < divs.length; i++) {
    var div = divs[i];
    var a = document.createElement("a");
    a.index = i;  
    a.innerText = "[this should point to Div" + (i+1) + "]";
    a.href = "#";
    a.addEventListener("click", function (e) {
        var e = e || window.event;
        var tg = e.target || e.srcElement;
        testDiv(divs[tg.index]);
    });
    document.body.appendChild(a);
}